root/trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

Revision 839, 68.1 kB (checked in by ppalmers, 14 years ago)

fix shutdown segfault

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 program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25
26 #include "StreamProcessor.h"
27 #include "../StreamProcessorManager.h"
28
29 #include "devicemanager.h"
30
31 #include "libieee1394/ieee1394service.h"
32 #include "libieee1394/IsoHandlerManager.h"
33 #include "libieee1394/cycletimer.h"
34
35 #include "libutil/Time.h"
36
37 #include "libutil/Atomic.h"
38
39 #include <assert.h>
40 #include <math.h>
41
42 /*
43 #define POST_SEMAPHORE { \
44     int tmp; \
45     sem_getvalue(&m_signal_semaphore, &tmp); \
46     debugWarning("posting semaphore from value %d\n", tmp); \
47     sem_post(&m_signal_semaphore); \
48 }
49 */
50
51 #define POST_SEMAPHORE { \
52     sem_post(&m_signal_semaphore); \
53 }
54
55 namespace Streaming {
56
57 IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_VERBOSE );
58
59 StreamProcessor::StreamProcessor(FFADODevice &parent, enum eProcessorType type)
60     : m_processor_type ( type )
61     , m_state( ePS_Created )
62     , m_next_state( ePS_Invalid )
63     , m_cycle_to_switch_state( 0 )
64     , m_Parent( parent )
65     , m_1394service( parent.get1394Service() ) // local cache
66     , m_IsoHandlerManager( parent.get1394Service().getIsoHandlerManager() ) // local cache
67     , m_StreamProcessorManager( m_Parent.getDeviceManager().getStreamProcessorManager() ) // local cache
68     , m_local_node_id ( 0 ) // local cache
69     , m_channel( -1 )
70     , m_dropped( 0 )
71     , m_last_timestamp( 0 )
72     , m_last_timestamp2( 0 )
73     , m_correct_last_timestamp( false )
74     , m_scratch_buffer( NULL )
75     , m_scratch_buffer_size_bytes( 0 )
76     , m_ticks_per_frame( 0 )
77     , m_last_cycle( -1 )
78     , m_sync_delay( 0 )
79     , m_in_xrun( false )
80     , m_signal_period( 0 )
81     , m_signal_offset( 0 )
82 {
83     // create the timestamped buffer and register ourselves as its client
84     m_data_buffer = new Util::TimestampedBuffer(this);
85 }
86
87 StreamProcessor::~StreamProcessor() {
88     m_StreamProcessorManager.unregisterProcessor(this);
89     if(!m_IsoHandlerManager.unregisterStream(this)) {
90         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister stream processor with the Iso manager\n");
91     }
92     // make the threads leave the wait condition
93     POST_SEMAPHORE;
94     sem_destroy(&m_signal_semaphore);
95
96     if (m_data_buffer) delete m_data_buffer;
97     if (m_scratch_buffer) delete[] m_scratch_buffer;
98 }
99
100 uint64_t StreamProcessor::getTimeNow() {
101     return m_1394service.getCycleTimerTicks();
102 }
103
104 int StreamProcessor::getMaxFrameLatency() {
105     if (getType() == ePT_Receive) {
106         return (int)(m_IsoHandlerManager.getPacketLatencyForStream( this ) * TICKS_PER_CYCLE);
107     } else {
108         return (int)(m_IsoHandlerManager.getPacketLatencyForStream( this ) * TICKS_PER_CYCLE);
109     }
110 }
111
112 unsigned int
113 StreamProcessor::getNominalPacketsNeeded(unsigned int nframes)
114 {
115     unsigned int nominal_frames_per_second
116                     = m_StreamProcessorManager.getNominalRate();
117     uint64_t nominal_ticks_per_frame = TICKS_PER_SECOND / nominal_frames_per_second;
118     uint64_t nominal_ticks = nominal_ticks_per_frame * nframes;
119     uint64_t nominal_packets = nominal_ticks / TICKS_PER_CYCLE;
120     return nominal_packets;
121 }
122
123 unsigned int
124 StreamProcessor::getPacketsPerPeriod()
125 {
126     return getNominalPacketsNeeded(m_StreamProcessorManager.getPeriodSize());
127 }
128
129 unsigned int
130 StreamProcessor::getNbPacketsIsoXmitBuffer()
131 {
132 #if ISOHANDLER_PER_HANDLER_THREAD
133     // if we use one thread per packet, we can put every frame directly into the ISO buffer
134     // the waitForClient in IsoHandler will take care of the fact that the frames are
135     // not present in time
136     unsigned int packets_to_prebuffer = (getPacketsPerPeriod() * (m_StreamProcessorManager.getNbBuffers())) + 10;
137     debugOutput(DEBUG_LEVEL_VERBOSE, "Nominal prebuffer: %u\n", packets_to_prebuffer);
138     return packets_to_prebuffer;
139 #else
140     // the target is to have all of the transmit buffer (at period transfer) as ISO packets
141     // when one period is received, there will be approx (NbBuffers - 1) * period_size frames
142     // in the transmit buffer (the others are still to be put into the xmit frame buffer)
143     unsigned int packets_to_prebuffer = (getPacketsPerPeriod() * (m_StreamProcessorManager.getNbBuffers()-1));
144     debugOutput(DEBUG_LEVEL_VERBOSE, "Nominal prebuffer: %u\n", packets_to_prebuffer);
145    
146     // however we have to take into account the fact that there is some sync delay
147     // we assume that the SPM has indicated
148     // HACK: this counts on the fact that the latency for this stream will be the same as the
149     //       latency for the receive sync source
150     unsigned int est_sync_delay = getPacketsPerPeriod() / MINIMUM_INTERRUPTS_PER_PERIOD;
151     est_sync_delay += STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS / TICKS_PER_CYCLE;
152     packets_to_prebuffer -= est_sync_delay;
153     debugOutput(DEBUG_LEVEL_VERBOSE, " correct for sync delay (%d): %u\n",
154                                      est_sync_delay,
155                                      packets_to_prebuffer);
156    
157     // only queue a part of the theoretical max in order not to have too much 'not ready' cycles
158     packets_to_prebuffer = (packets_to_prebuffer * MAX_ISO_XMIT_BUFFER_FILL_PCT * 1000) / 100000;
159     debugOutput(DEBUG_LEVEL_VERBOSE, " reduce to %d%%: %u\n",
160                                      MAX_ISO_XMIT_BUFFER_FILL_PCT, packets_to_prebuffer);
161    
162     return packets_to_prebuffer;
163 #endif
164 }
165
166 /***********************************************
167  * Buffer management and manipulation          *
168  ***********************************************/
169 void StreamProcessor::flush() {
170     m_IsoHandlerManager.flushHandlerForStream(this);
171 }
172
173 int StreamProcessor::getBufferFill() {
174     return m_data_buffer->getBufferFill();
175 }
176
177 int64_t
178 StreamProcessor::getTimeUntilNextPeriodSignalUsecs()
179 {
180     uint64_t time_at_period=getTimeAtPeriod();
181
182     // we delay the period signal with the sync delay
183     // this makes that the period signals lag a little compared to reality
184     // ISO buffering causes the packets to be received at max
185     // m_handler->getWakeupInterval() later than the time they were received.
186     // hence their payload is available this amount of time later. However, the
187     // period boundary is predicted based upon earlier samples, and therefore can
188     // pass before these packets are processed. Adding this extra term makes that
189     // the period boundary is signalled later
190     time_at_period = addTicks(time_at_period, m_StreamProcessorManager.getSyncSource().getSyncDelay());
191
192     uint64_t cycle_timer=m_1394service.getCycleTimerTicks();
193
194     // calculate the time until the next period
195     int32_t until_next=diffTicks(time_at_period,cycle_timer);
196
197     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11ld\n",
198         time_at_period, cycle_timer, until_next
199         );
200
201     // now convert to usecs
202     // don't use the mapping function because it only works
203     // for absolute times, not the relative time we are
204     // using here (which can also be negative).
205     return (int64_t)(((float)until_next) / TICKS_PER_USEC);
206 }
207
208 void
209 StreamProcessor::setSyncDelay(int d) {
210     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "Setting SP %p SyncDelay to %d ticks\n", this, d);
211     m_sync_delay = d;
212 }
213
214 uint64_t
215 StreamProcessor::getTimeAtPeriodUsecs()
216 {
217     return (uint64_t)((float)getTimeAtPeriod() * TICKS_PER_USEC);
218 }
219
220 uint64_t
221 StreamProcessor::getTimeAtPeriod()
222 {
223     if (getType() == ePT_Receive) {
224         ffado_timestamp_t next_period_boundary=m_data_buffer->getTimestampFromHead(m_StreamProcessorManager.getPeriodSize());
225    
226         #ifdef DEBUG
227         ffado_timestamp_t ts;
228         signed int fc;
229         m_data_buffer->getBufferTailTimestamp(&ts,&fc);
230    
231         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD="TIMESTAMP_FORMAT_SPEC", LTS="TIMESTAMP_FORMAT_SPEC", FC=%5u, TPF=%f\n",
232             next_period_boundary, ts, fc, getTicksPerFrame()
233             );
234         #endif
235         return (uint64_t)next_period_boundary;
236     } else {
237         ffado_timestamp_t next_period_boundary=m_data_buffer->getTimestampFromTail((m_StreamProcessorManager.getNbBuffers()-1) * m_StreamProcessorManager.getPeriodSize());
238    
239         #ifdef DEBUG
240         ffado_timestamp_t ts;
241         signed int fc;
242         m_data_buffer->getBufferTailTimestamp(&ts,&fc);
243    
244         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD="TIMESTAMP_FORMAT_SPEC", LTS="TIMESTAMP_FORMAT_SPEC", FC=%5u, TPF=%f\n",
245             next_period_boundary, ts, fc, getTicksPerFrame()
246             );
247         #endif
248         return (uint64_t)next_period_boundary;
249     }
250 }
251
252 float
253 StreamProcessor::getTicksPerFrame()
254 {
255     assert(m_data_buffer != NULL);
256     return m_data_buffer->getRate();
257 }
258
259 bool
260 StreamProcessor::canClientTransferFrames(unsigned int nbframes)
261 {
262     bool can_transfer;
263     unsigned int fc = m_data_buffer->getFrameCounter();
264     if (getType() == ePT_Receive) {
265         can_transfer = (fc >= nbframes);
266     } else {
267         // there has to be enough space to put the frames in
268         can_transfer = m_data_buffer->getBufferSize() - fc > nbframes;
269         // or the buffer is transparent
270         can_transfer |= m_data_buffer->isTransparent();
271     }
272    
273     #ifdef DEBUG
274     if (!can_transfer) {
275         debugWarning("(%p, %s) cannot transfer since fc == %u, nbframes == %u\n",
276             this, ePTToString(getType()), fc, nbframes);
277     }
278     #endif
279    
280     return can_transfer;
281 }
282
283 /***********************************************
284  * I/O API                                     *
285  ***********************************************/
286
287 // Packet transfer API
288 enum raw1394_iso_disposition
289 StreamProcessor::putPacket(unsigned char *data, unsigned int length,
290                            unsigned char channel, unsigned char tag, unsigned char sy,
291                            unsigned int cycle, unsigned int dropped) {
292 #ifdef DEBUG
293     if(m_last_cycle == -1) {
294         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle);
295     }
296 #endif
297
298     int dropped_cycles = 0;
299     if (m_last_cycle != (int)cycle && m_last_cycle != -1) {
300         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
301         if (dropped_cycles < 0) {
302             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",
303                          this, dropped_cycles, cycle, m_last_cycle, dropped);
304         }
305         if (dropped_cycles > 0) {
306             debugWarning("(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n",
307                 this, dropped_cycles, cycle, dropped, cycle, m_last_cycle);
308             m_dropped += dropped_cycles;
309             m_last_cycle = cycle;
310         }
311     }
312     m_last_cycle = cycle;
313
314     // bypass based upon state
315     if (m_state == ePS_Invalid) {
316         debugError("Should not have state %s\n", ePSToString(m_state) );
317         POST_SEMAPHORE;
318         return RAW1394_ISO_ERROR;
319     }
320     if (m_state == ePS_Created) {
321         return RAW1394_ISO_DEFER;
322     }
323
324     // store the previous timestamp
325     m_last_timestamp2 = m_last_timestamp;
326
327     // NOTE: synchronized switching is restricted to a 0.5 sec span (4000 cycles)
328     //       it happens on the first 'good' cycle for the wait condition
329     //       or on the first received cycle that is received afterwards (might be a problem)
330
331     // check whether we are waiting for a stream to be disabled
332     if(m_state == ePS_WaitingForStreamDisable) {
333         // we then check whether we have to switch on this cycle
334         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
335             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning\n");
336             m_next_state = ePS_DryRunning;
337             if (!updateState()) { // we are allowed to change the state directly
338                 debugError("Could not update state!\n");
339                 POST_SEMAPHORE;
340                 return RAW1394_ISO_ERROR;
341             }
342         } else {
343             // not time to disable yet
344         }
345         // the received data can be discarded while waiting for the stream
346         // to be disabled
347         // similarly for dropped packets
348         return RAW1394_ISO_OK;
349     }
350
351     // check whether we are waiting for a stream to be enabled
352     else if(m_state == ePS_WaitingForStreamEnable) {
353         // we then check whether we have to switch on this cycle
354         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
355             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to Running\n");
356             m_next_state = ePS_Running;
357             if (!updateState()) { // we are allowed to change the state directly
358                 debugError("Could not update state!\n");
359                 POST_SEMAPHORE;
360                 return RAW1394_ISO_ERROR;
361             }
362         } else {
363             // not time to enable yet
364         }
365         // we are dryRunning hence data should be processed in any case
366     }
367
368     // check the packet header
369     enum eChildReturnValue result = processPacketHeader(data, length, channel, tag, sy, cycle, dropped_cycles);
370
371     // handle dropped cycles
372     if(dropped_cycles) {
373         // make sure the last_timestamp is corrected
374         m_correct_last_timestamp = true;
375         if (m_state == ePS_Running) {
376             // this is an xrun situation
377             m_in_xrun = true;
378             debugWarning("Should update state to WaitingForStreamDisable due to dropped packet xrun\n");
379             m_cycle_to_switch_state = cycle + 1; // switch in the next cycle
380             m_next_state = ePS_WaitingForStreamDisable;
381             // execute the requested change
382             if (!updateState()) { // we are allowed to change the state directly
383                 debugError("Could not update state!\n");
384                 POST_SEMAPHORE;
385                 return RAW1394_ISO_ERROR;
386             }
387         }
388     }
389
390     if (result == eCRV_OK) {
391         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n",
392                 cycle, m_last_timestamp);
393         // update some accounting
394         m_last_good_cycle = cycle;
395         m_last_dropped = dropped_cycles;
396
397         if(m_correct_last_timestamp) {
398             // they represent a discontinuity in the timestamps, and hence are
399             // to be dealt with
400             debugWarning("(%p) Correcting timestamp for dropped cycles, discarding packet...\n", this);
401             m_data_buffer->setBufferTailTimestamp(substractTicks(m_last_timestamp, getNominalFramesPerPacket() * getTicksPerFrame()));
402             m_correct_last_timestamp = false;
403         }
404
405         // check whether we are waiting for a stream to startup
406         // this requires that the packet is good
407         if(m_state == ePS_WaitingForStream) {
408             // since we have a packet with an OK header,
409             // we can indicate that the stream started up
410
411             // we then check whether we have to switch on this cycle
412             if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
413                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning due to good packet\n");
414                 // hence go to the dryRunning state
415                 m_next_state = ePS_DryRunning;
416                 if (!updateState()) { // we are allowed to change the state directly
417                     debugError("Could not update state!\n");
418                     POST_SEMAPHORE;
419                     return RAW1394_ISO_ERROR;
420                 }
421             } else {
422                 // not time (yet) to switch state
423             }
424             // in both cases we don't want to process the data
425             return RAW1394_ISO_OK;
426         }
427
428         // check whether a state change has been requested
429         // note that only the wait state changes are synchronized with the cycles
430         else if(m_state != m_next_state) {
431             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
432                                              ePSToString(m_state), ePSToString(m_next_state));
433             // execute the requested change
434             if (!updateState()) { // we are allowed to change the state directly
435                 debugError("Could not update state!\n");
436                 POST_SEMAPHORE;
437                 return RAW1394_ISO_ERROR;
438             }
439         }
440
441         // for all states that reach this we are allowed to
442         // do protocol specific data reception
443         enum eChildReturnValue result2 = processPacketData(data, length, channel, tag, sy, cycle, dropped_cycles);
444
445         // if an xrun occured, switch to the dryRunning state and
446         // allow for the xrun to be picked up
447         if (result2 == eCRV_XRun) {
448             debugWarning("processPacketData xrun\n");
449             m_in_xrun = true;
450             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n");
451             m_cycle_to_switch_state = cycle+1; // switch in the next cycle
452             m_next_state = ePS_WaitingForStreamDisable;
453             // execute the requested change
454             if (!updateState()) { // we are allowed to change the state directly
455                 debugError("Could not update state!\n");
456                 POST_SEMAPHORE;
457                 return RAW1394_ISO_ERROR;
458             }
459             POST_SEMAPHORE;
460             return RAW1394_ISO_DEFER;
461         } else if(result2 == eCRV_OK) {
462             // no problem here
463             // if we have enough samples, we can post the semaphore and
464             // defer further processing until later. this will allow us to
465             // run the client and process the frames such that we can put them
466             // into the xmit buffers ASAP
467             if (m_state == ePS_Running) {
468                 unsigned int bufferfill = m_data_buffer->getBufferFill();
469                 if(bufferfill >= m_signal_period + m_signal_offset) {
470                     // this to avoid multiple signals for the same period
471                     int semval;
472                     sem_getvalue(&m_signal_semaphore, &semval);
473                     unsigned int signal_period = m_signal_period * (semval + 1) + m_signal_offset;
474                     if(bufferfill >= signal_period) {
475                         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) buffer fill (%d) > signal period (%d), sem_val=%d\n",
476                                     this, m_data_buffer->getBufferFill(), signal_period, semval);
477                         POST_SEMAPHORE;
478                     }
479                     // the process thread should have higher prio such that we are blocked until
480                     // the samples are processed.
481                     return RAW1394_ISO_DEFER;
482                 }
483             }
484             return RAW1394_ISO_OK;
485         } else {
486             debugError("Invalid response\n");
487             POST_SEMAPHORE;
488             return RAW1394_ISO_ERROR;
489         }
490     } else if(result == eCRV_Invalid) {
491         // apparently we don't have to do anything when the packets are not valid
492         return RAW1394_ISO_OK;
493     } else {
494         debugError("Invalid response\n");
495         POST_SEMAPHORE;
496         return RAW1394_ISO_ERROR;
497     }
498     debugError("reached the unreachable\n");
499     POST_SEMAPHORE;
500     return RAW1394_ISO_ERROR;
501 }
502
503 enum raw1394_iso_disposition
504 StreamProcessor::getPacket(unsigned char *data, unsigned int *length,
505                            unsigned char *tag, unsigned char *sy,
506                            int cycle, unsigned int dropped, unsigned int max_length) {
507     if (cycle<0) {
508         *tag = 0;
509         *sy = 0;
510         *length = 0;
511         return RAW1394_ISO_OK;
512     }
513
514     unsigned int ctr;
515     int now_cycles;
516     int cycle_diff;
517
518 #ifdef DEBUG
519     if(m_last_cycle == -1) {
520         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle);
521     }
522 #endif
523
524     int dropped_cycles = 0;
525     if (m_last_cycle != cycle && m_last_cycle != -1) {
526         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
527         if (dropped_cycles < 0) {
528             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",
529                          this, dropped_cycles, cycle, m_last_cycle, dropped);
530         }
531         if (dropped_cycles > 0) {
532             debugWarning("(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d)\n", this, dropped_cycles, cycle, m_last_cycle, dropped);
533             m_dropped += dropped_cycles;
534             // HACK: this should not be necessary, since the header generation functions should trigger the xrun.
535             //       but apparently there are some issues with the 1394 stack
536             m_in_xrun = true;
537             if(m_state == ePS_Running) {
538                 debugShowBackLogLines(200);
539                 debugWarning("dropped packets xrun\n");
540                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packets xrun\n");
541                 m_cycle_to_switch_state = cycle + 1;
542                 m_next_state = ePS_WaitingForStreamDisable;
543                 // execute the requested change
544                 if (!updateState()) { // we are allowed to change the state directly
545                     debugError("Could not update state!\n");
546                     return RAW1394_ISO_ERROR;
547                 }
548                 goto send_empty_packet;
549             }
550         }
551     }
552     if (cycle >= 0) {
553         m_last_cycle = cycle;
554     }
555
556 #ifdef DEBUG
557     // bypass based upon state
558     if (m_state == ePS_Invalid) {
559         debugError("Should not have state %s\n", ePSToString(m_state) );
560         return RAW1394_ISO_ERROR;
561     }
562 #endif
563
564     if (m_state == ePS_Created) {
565         *tag = 0;
566         *sy = 0;
567         *length = 0;
568         return RAW1394_ISO_DEFER;
569     }
570
571     // normal processing
572     // note that we can't use getCycleTimer directly here,
573     // because packets are queued in advance. This means that
574     // we the packet we are constructing will be sent out
575     // on 'cycle', not 'now'.
576     ctr = m_1394service.getCycleTimer();
577     now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
578
579     // the difference between the cycle this
580     // packet is intended for and 'now'
581     cycle_diff = diffCycles(cycle, now_cycles);
582
583     if(cycle_diff < 0 && (m_state == ePS_Running || m_state == ePS_DryRunning)) {
584         debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n",
585             cycle, now_cycles);
586         if(m_state == ePS_Running) {
587             debugShowBackLogLines(200);
588 //             flushDebugOutput();
589 //             assert(0);
590             debugWarning("generatePacketData xrun\n");
591             m_in_xrun = true;
592             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n");
593             m_cycle_to_switch_state = cycle + 1;
594             m_next_state = ePS_WaitingForStreamDisable;
595             // execute the requested change
596             if (!updateState()) { // we are allowed to change the state directly
597                 debugError("Could not update state!\n");
598                 return RAW1394_ISO_ERROR;
599             }
600             goto send_empty_packet;
601         }
602     }
603
604     // store the previous timestamp
605     m_last_timestamp2 = m_last_timestamp;
606
607     // NOTE: synchronized switching is restricted to a 0.5 sec span (4000 cycles)
608     //       it happens on the first 'good' cycle for the wait condition
609     //       or on the first received cycle that is received afterwards (might be a problem)
610
611     // check whether we are waiting for a stream to be disabled
612     if(m_state == ePS_WaitingForStreamDisable) {
613         // we then check whether we have to switch on this cycle
614         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
615             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning\n");
616             m_next_state = ePS_DryRunning;
617             if (!updateState()) { // we are allowed to change the state directly
618                 debugError("Could not update state!\n");
619                 return RAW1394_ISO_ERROR;
620             }
621         } else {
622             // not time to disable yet
623         }
624     }
625     // check whether we are waiting for a stream to be enabled
626     else if(m_state == ePS_WaitingForStreamEnable) {
627         // we then check whether we have to switch on this cycle
628         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
629             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to Running\n");
630             m_next_state = ePS_Running;
631             if (!updateState()) { // we are allowed to change the state directly
632                 debugError("Could not update state!\n");
633                 return RAW1394_ISO_ERROR;
634             }
635         } else {
636             // not time to enable yet
637         }
638         // we are dryRunning hence data should be processed in any case
639     }
640     // check whether we are waiting for a stream to startup
641     else if(m_state == ePS_WaitingForStream) {
642         // as long as the cycle parameter is not in sync with
643         // the current time, the stream is considered not
644         // to be 'running'
645         // we then check whether we have to switch on this cycle
646         if ((cycle_diff >= 0) && (diffCycles(cycle, m_cycle_to_switch_state) >= 0)) {
647             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStream to DryRunning\n");
648             // hence go to the dryRunning state
649             m_next_state = ePS_DryRunning;
650             if (!updateState()) { // we are allowed to change the state directly
651                 debugError("Could not update state!\n");
652                 return RAW1394_ISO_ERROR;
653             }
654         } else {
655             // not time (yet) to switch state
656         }
657     }
658     else if(m_state == ePS_Running) {
659         // check the packet header
660         enum eChildReturnValue result = generatePacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
661         if (result == eCRV_Packet || result == eCRV_Defer) {
662             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT: CY=%04u TS=%011llu\n",
663                     cycle, m_last_timestamp);
664             // update some accounting
665             m_last_good_cycle = cycle;
666             m_last_dropped = dropped_cycles;
667
668             // check whether a state change has been requested
669             // note that only the wait state changes are synchronized with the cycles
670             if(m_state != m_next_state) {
671                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
672                                                 ePSToString(m_state), ePSToString(m_next_state));
673                 // execute the requested change
674                 if (!updateState()) { // we are allowed to change the state directly
675                     debugError("Could not update state!\n");
676                     return RAW1394_ISO_ERROR;
677                 }
678             }
679
680             enum eChildReturnValue result2 = generatePacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
681             // if an xrun occured, switch to the dryRunning state and
682             // allow for the xrun to be picked up
683             if (result2 == eCRV_XRun) {
684                 debugWarning("generatePacketData xrun\n");
685                 m_in_xrun = true;
686                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n");
687                 m_cycle_to_switch_state = cycle + 1; // switch in the next cycle
688                 m_next_state = ePS_WaitingForStreamDisable;
689                 // execute the requested change
690                 if (!updateState()) { // we are allowed to change the state directly
691                     debugError("Could not update state!\n");
692                     return RAW1394_ISO_ERROR;
693                 }
694                 goto send_empty_packet;
695             }
696             // skip queueing packets if we detect that there are not enough frames
697             // available
698             if(result2 == eCRV_Defer || result == eCRV_Defer)
699                 return RAW1394_ISO_DEFER;
700             else
701                 return RAW1394_ISO_OK;
702         } else if (result == eCRV_XRun) { // pick up the possible xruns
703             debugWarning("generatePacketHeader xrun\n");
704             m_in_xrun = true;
705             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n");
706             m_cycle_to_switch_state = cycle + 1; // switch in the next cycle
707             m_next_state = ePS_WaitingForStreamDisable;
708             // execute the requested change
709             if (!updateState()) { // we are allowed to change the state directly
710                 debugError("Could not update state!\n");
711                 return RAW1394_ISO_ERROR;
712             }
713         } else if (result == eCRV_EmptyPacket) {
714             if(m_state != m_next_state) {
715                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
716                                                 ePSToString(m_state), ePSToString(m_next_state));
717                 // execute the requested change
718                 if (!updateState()) { // we are allowed to change the state directly
719                     debugError("Could not update state!\n");
720                     return RAW1394_ISO_ERROR;
721                 }
722             }
723             goto send_empty_packet;
724         } else if (result == eCRV_Again) {
725             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle);
726             if(m_state != m_next_state) {
727                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
728                                                 ePSToString(m_state), ePSToString(m_next_state));
729                 // execute the requested change
730                 if (!updateState()) { // we are allowed to change the state directly
731                     debugError("Could not update state!\n");
732                     return RAW1394_ISO_ERROR;
733                 }
734             }
735             usleep(125); // only when using thread-per-handler
736             return RAW1394_ISO_AGAIN;
737 //             generateSilentPacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
738 //             generateSilentPacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
739 //             return RAW1394_ISO_DEFER;
740         } else {
741             debugError("Invalid return value: %d\n", result);
742             return RAW1394_ISO_ERROR;
743         }
744     }
745     // we are not running, so send an empty packet
746     // we should generate a valid packet any time
747 send_empty_packet:
748     // note that only the wait state changes are synchronized with the cycles
749     if(m_state != m_next_state) {
750         debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
751                                         ePSToString(m_state), ePSToString(m_next_state));
752         // execute the requested change
753         if (!updateState()) { // we are allowed to change the state directly
754             debugError("Could not update state!\n");
755             return RAW1394_ISO_ERROR;
756         }
757     }
758
759     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT EMPTY: CY=%04u\n", cycle);
760     generateSilentPacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
761     generateSilentPacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
762     return RAW1394_ISO_OK;
763 }
764
765
766 // Frame Transfer API
767 /**
768  * Transfer a block of frames from the event buffer to the port buffers
769  * @param nbframes number of frames to transfer
770  * @param ts the timestamp that the LAST frame in the block should have
771  * @return
772  */
773 bool StreamProcessor::getFrames(unsigned int nbframes, int64_t ts) {
774     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p.getFrames(%d, %11llu)", nbframes, ts);
775     assert( getType() == ePT_Receive );
776     if(isDryRunning()) return getFramesDry(nbframes, ts);
777     else return getFramesWet(nbframes, ts);
778 }
779
780 bool StreamProcessor::getFramesWet(unsigned int nbframes, int64_t ts) {
781 // FIXME: this should be done somewhere else
782 #ifdef DEBUG
783     uint64_t ts_expected;
784     signed int fc;
785     int32_t lag_ticks;
786     float lag_frames;
787
788     // in order to sync up multiple received streams, we should
789     // use the ts parameter. It specifies the time of the block's
790     // last sample.
791     float srate = m_StreamProcessorManager.getSyncSource().getTicksPerFrame();
792     assert(srate != 0.0);
793     int64_t this_block_length_in_ticks = (int64_t)(((float)nbframes) * srate);
794
795     ffado_timestamp_t ts_head_tmp;
796     m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc);
797     ts_expected = addTicks((uint64_t)ts_head_tmp, this_block_length_in_ticks);
798
799     lag_ticks = diffTicks(ts, ts_expected);
800     lag_frames = (((float)lag_ticks) / srate);
801     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): drifts %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
802                  this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
803     if (lag_frames >= 1.0) {
804         // the stream lags
805         debugWarning( "stream (%p): lags  with %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
806                       this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
807     } else if (lag_frames <= -1.0) {
808         // the stream leads
809         debugWarning( "stream (%p): leads with %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
810                       this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
811     }
812 #endif
813     // ask the buffer to process nbframes of frames
814     // using it's registered client's processReadBlock(),
815     // which should be ours
816     m_data_buffer->blockProcessReadFrames(nbframes);
817     return true;
818 }
819
820 bool StreamProcessor::getFramesDry(unsigned int nbframes, int64_t ts)
821 {
822     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): dry run %d frames (@ ts=%lld)\n",
823                  this, nbframes, ts);
824     // dry run on this side means that we put silence in all enabled ports
825     // since there is do data put into the ringbuffer in the dry-running state
826     return provideSilenceBlock(nbframes, 0);
827 }
828
829 bool
830 StreamProcessor::dropFrames(unsigned int nbframes, int64_t ts)
831 {
832     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "StreamProcessor::dropFrames(%d, %lld)\n", nbframes, ts);
833     return m_data_buffer->dropFrames(nbframes);
834 }
835
836 bool StreamProcessor::putFrames(unsigned int nbframes, int64_t ts)
837 {
838     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p.putFrames(%d, %11llu)", nbframes, ts);
839     assert( getType() == ePT_Transmit );
840
841     if(isDryRunning()) return putFramesDry(nbframes, ts);
842     else return putFramesWet(nbframes, ts);
843 }
844
845 bool
846 StreamProcessor::putFramesWet(unsigned int nbframes, int64_t ts)
847 {
848     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putFramesWet(%d, %llu)\n", nbframes, ts);
849     // transfer the data
850     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
851     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
852
853     unsigned int bufferfill = m_data_buffer->getBufferFill();
854     if (bufferfill >= m_signal_period + m_signal_offset) {
855         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n",
856                                          this, bufferfill, m_signal_period + m_signal_offset);
857         POST_SEMAPHORE;
858     } else {
859         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n",
860                                          this, bufferfill, m_signal_period + m_signal_offset);
861     }
862     return true; // FIXME: what about failure?
863 }
864
865 bool
866 StreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts)
867 {
868     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts);
869     // do nothing
870     return true;
871 }
872
873 bool
874 StreamProcessor::putSilenceFrames(unsigned int nbframes, int64_t ts)
875 {
876     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putSilenceFrames(%d, %llu)\n", nbframes, ts);
877
878     size_t bytes_per_frame = getEventSize() * getEventsPerFrame();
879     unsigned int scratch_buffer_size_frames = m_scratch_buffer_size_bytes / bytes_per_frame;
880
881     if (nbframes > scratch_buffer_size_frames) {
882         debugError("nframes (%u) > scratch_buffer_size_frames (%u)\n",
883                    nbframes, scratch_buffer_size_frames);
884     }
885
886     assert(m_scratch_buffer);
887     if(!transmitSilenceBlock((char *)m_scratch_buffer, nbframes, 0)) {
888         debugError("Could not prepare silent block\n");
889         return false;
890     }
891     if(!m_data_buffer->writeFrames(nbframes, (char *)m_scratch_buffer, ts)) {
892         debugError("Could not write silent block\n");
893         return false;
894     }
895
896     unsigned int bufferfill = m_data_buffer->getBufferFill();
897     if (bufferfill >= m_signal_period + m_signal_offset) {
898         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n",
899                                          this, bufferfill, m_signal_period + m_signal_offset);
900         POST_SEMAPHORE;
901     } else {
902         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n",
903                                          this, bufferfill, m_signal_period + m_signal_offset);
904     }
905
906     return true;
907 }
908
909 bool
910 StreamProcessor::waitForSignal()
911 {
912     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) wait ...\n", this, getTypeString());
913     int result;
914     if(m_state == ePS_Running && m_next_state == ePS_Running) {
915         result = sem_wait(&m_signal_semaphore);
916 #ifdef DEBUG
917         int tmp;
918         sem_getvalue(&m_signal_semaphore, &tmp);
919         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp);
920 #endif
921         return result == 0;
922     } else {
923         // when we're not running, we can always provide frames
924         // when we're in a state transition, keep iterating too
925         debugOutput(DEBUG_LEVEL_VERBOSE, "Not running...\n");
926         return true;
927     }
928 }
929
930 bool
931 StreamProcessor::tryWaitForSignal()
932 {
933     if(m_state == ePS_Running) {
934         return sem_trywait(&m_signal_semaphore) == 0;
935     } else {
936         // when we're not running, we can always provide frames
937         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Not running...\n");
938         return true;
939     }
940 }
941
942 bool
943 StreamProcessor::canProcessPackets()
944 {
945     if(m_state != ePS_Running || m_next_state != ePS_Running) return true;
946     bool result;
947     unsigned int bufferfill;
948     if(getType() == ePT_Receive) {
949         bufferfill = m_data_buffer->getBufferSpace();
950     } else {
951         bufferfill = m_data_buffer->getBufferFill();
952     }
953     result = bufferfill > getNominalFramesPerPacket();
954 //     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) for a bufferfill of %d, we return %d\n",
955 //                 this, ePTToString(getType()), bufferfill, result);
956     return result;
957 }
958
959 bool
960 StreamProcessor::shiftStream(int nbframes)
961 {
962     if(nbframes == 0) return true;
963     if(nbframes > 0) {
964         return m_data_buffer->dropFrames(nbframes);
965     } else {
966         bool result = true;
967         while(nbframes++) {
968             result &= m_data_buffer->writeDummyFrame();
969         }
970         return result;
971     }
972 }
973
974 /**
975  * @brief write silence events to the stream ringbuffers.
976  */
977 bool StreamProcessor::provideSilenceBlock(unsigned int nevents, unsigned int offset)
978 {
979     bool no_problem=true;
980     for ( PortVectorIterator it = m_Ports.begin();
981           it != m_Ports.end();
982           ++it ) {
983         if((*it)->isDisabled()) {continue;};
984
985         if(provideSilenceToPort((*it), offset, nevents)) {
986             debugWarning("Could not put silence into to port %s",(*it)->getName().c_str());
987             no_problem=false;
988         }
989     }
990     return no_problem;
991 }
992
993 int
994 StreamProcessor::provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents)
995 {
996     unsigned int j=0;
997     switch(p->getPortType()) {
998         default:
999             debugError("Invalid port type: %d\n", p->getPortType());
1000             return -1;
1001         case Port::E_Midi:
1002         case Port::E_Control:
1003             {
1004                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1005                 assert(nevents + offset <= p->getBufferSize());
1006                 buffer+=offset;
1007
1008                 for(j = 0; j < nevents; j += 1) {
1009                     *(buffer)=0;
1010                     buffer++;
1011                 }
1012             }
1013             break;
1014         case Port::E_Audio:
1015             switch(m_StreamProcessorManager.getAudioDataType()) {
1016             case StreamProcessorManager::eADT_Int24:
1017                 {
1018                     quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1019                     assert(nevents + offset <= p->getBufferSize());
1020                     buffer+=offset;
1021    
1022                     for(j = 0; j < nevents; j += 1) {
1023                         *(buffer)=0;
1024                         buffer++;
1025                     }
1026                 }
1027                 break;
1028             case StreamProcessorManager::eADT_Float:
1029                 {
1030                     float *buffer=(float *)(p->getBufferAddress());
1031                     assert(nevents + offset <= p->getBufferSize());
1032                     buffer+=offset;
1033    
1034                     for(j = 0; j < nevents; j += 1) {
1035                         *buffer = 0.0;
1036                         buffer++;
1037                     }
1038                 }
1039                 break;
1040             }
1041             break;
1042     }
1043     return 0;
1044 }
1045
1046 /***********************************************
1047  * State related API                           *
1048  ***********************************************/
1049 bool StreamProcessor::init()
1050 {
1051     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "init...\n");
1052
1053     if (sem_init(&m_signal_semaphore, 0, 0) == -1) {
1054         debugError("Could not init signal semaphore");
1055         return false;
1056     }
1057
1058     if(!m_IsoHandlerManager.registerStream(this)) {
1059         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register stream processor with the Iso manager\n");
1060         return false;
1061     }
1062     if(!m_StreamProcessorManager.registerProcessor(this)) {
1063         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register stream processor with the SP manager\n");
1064         return false;
1065     }
1066
1067     // initialization can be done without requesting it
1068     // from the packet loop
1069     m_next_state = ePS_Created;
1070     return true;
1071 }
1072
1073 bool StreamProcessor::prepare()
1074 {
1075     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare SP (%p)...\n", this);
1076
1077     // make the scratch buffer one period of frames long
1078     m_scratch_buffer_size_bytes = m_StreamProcessorManager.getPeriodSize() * getEventsPerFrame() * getEventSize();
1079     debugOutput( DEBUG_LEVEL_VERBOSE, " Allocate scratch buffer of %d quadlets\n");
1080     if(m_scratch_buffer) delete[] m_scratch_buffer;
1081     m_scratch_buffer = new byte_t[m_scratch_buffer_size_bytes];
1082     if(m_scratch_buffer == NULL) {
1083         debugFatal("Could not allocate scratch buffer\n");
1084         return false;
1085     }
1086
1087     // set the parameters of ports we can:
1088     // we want the audio ports to be period buffered,
1089     // and the midi ports to be packet buffered
1090     for ( PortVectorIterator it = m_Ports.begin();
1091         it != m_Ports.end();
1092         ++it )
1093     {
1094         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1095         if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) {
1096             debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize());
1097             return false;
1098         }
1099     }
1100     // the API specific settings of the ports should already be set,
1101     // as this is called from the processorManager->prepare()
1102     // so we can init the ports
1103     if(!PortManager::initPorts()) {
1104         debugFatal("Could not initialize ports\n");
1105         return false;
1106     }
1107
1108     if (!prepareChild()) {
1109         debugFatal("Could not prepare child\n");
1110         return false;
1111     }
1112
1113     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
1114     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d\n",
1115              m_StreamProcessorManager.getNominalRate());
1116     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
1117              m_StreamProcessorManager.getPeriodSize(), m_StreamProcessorManager.getNbBuffers());
1118     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
1119              m_1394service.getPort(), m_channel);
1120
1121     // initialization can be done without requesting it
1122     // from the packet loop
1123     m_next_state = ePS_Stopped;
1124     return updateState();
1125 }
1126
1127 bool
1128 StreamProcessor::scheduleStateTransition(enum eProcessorState state, uint64_t time_instant)
1129 {
1130     // first set the time, since in the packet loop we first check m_state == m_next_state before
1131     // using the time
1132     m_cycle_to_switch_state = TICKS_TO_CYCLES(time_instant);
1133     m_next_state = state;
1134     POST_SEMAPHORE; // needed to ensure that things don't get deadlocked
1135     return true;
1136 }
1137
1138 bool
1139 StreamProcessor::waitForState(enum eProcessorState state, unsigned int timeout_ms)
1140 {
1141     debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting for state %s\n", ePSToString(state));
1142     int cnt = timeout_ms;
1143     while (m_state != state && cnt) {
1144         SleepRelativeUsec(1000);
1145         cnt--;
1146     }
1147     if(cnt==0) {
1148         debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout\n");
1149         return false;
1150     }
1151     return true;
1152 }
1153
1154 bool StreamProcessor::scheduleStartDryRunning(int64_t t) {
1155     uint64_t tx;
1156     if (t < 0) {
1157         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1158     } else {
1159         tx = t;
1160     }
1161     uint64_t start_handler_ticks = substractTicks(tx, 100 * TICKS_PER_CYCLE);
1162
1163     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1164     uint64_t now = m_1394service.getCycleTimerTicks();
1165     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1166                           now,
1167                           (unsigned int)TICKS_TO_SECS(now),
1168                           (unsigned int)TICKS_TO_CYCLES(now),
1169                           (unsigned int)TICKS_TO_OFFSET(now));
1170     debugOutput(DEBUG_LEVEL_VERBOSE,"  Start at              : %011llu (%03us %04uc %04ut)\n",
1171                           tx,
1172                           (unsigned int)TICKS_TO_SECS(tx),
1173                           (unsigned int)TICKS_TO_CYCLES(tx),
1174                           (unsigned int)TICKS_TO_OFFSET(tx));
1175     if (m_state == ePS_Stopped) {
1176         if(!m_IsoHandlerManager.startHandlerForStream(
1177                                         this, TICKS_TO_CYCLES(start_handler_ticks))) {
1178             debugError("Could not start handler for SP %p\n", this);
1179             return false;
1180         }
1181         return scheduleStateTransition(ePS_WaitingForStream, tx);
1182     } else if (m_state == ePS_Running) {
1183         return scheduleStateTransition(ePS_WaitingForStreamDisable, tx);
1184     } else {
1185         debugError("Cannot switch to ePS_DryRunning from %s\n", ePSToString(m_state));
1186         return false;
1187     }
1188 }
1189
1190 bool StreamProcessor::scheduleStartRunning(int64_t t) {
1191     uint64_t tx;
1192     if (t < 0) {
1193         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1194     } else {
1195         tx = t;
1196     }
1197     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1198     uint64_t now = m_1394service.getCycleTimerTicks();
1199     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1200                           now,
1201                           (unsigned int)TICKS_TO_SECS(now),
1202                           (unsigned int)TICKS_TO_CYCLES(now),
1203                           (unsigned int)TICKS_TO_OFFSET(now));
1204     debugOutput(DEBUG_LEVEL_VERBOSE,"  Start at              : %011llu (%03us %04uc %04ut)\n",
1205                           tx,
1206                           (unsigned int)TICKS_TO_SECS(tx),
1207                           (unsigned int)TICKS_TO_CYCLES(tx),
1208                           (unsigned int)TICKS_TO_OFFSET(tx));
1209     return scheduleStateTransition(ePS_WaitingForStreamEnable, tx);
1210 }
1211
1212 bool StreamProcessor::scheduleStopDryRunning(int64_t t) {
1213     uint64_t tx;
1214     if (t < 0) {
1215         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1216     } else {
1217         tx = t;
1218     }
1219     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1220     uint64_t now = m_1394service.getCycleTimerTicks();
1221     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1222                           now,
1223                           (unsigned int)TICKS_TO_SECS(now),
1224                           (unsigned int)TICKS_TO_CYCLES(now),
1225                           (unsigned int)TICKS_TO_OFFSET(now));
1226     debugOutput(DEBUG_LEVEL_VERBOSE,"  Stop at               : %011llu (%03us %04uc %04ut)\n",
1227                           tx,
1228                           (unsigned int)TICKS_TO_SECS(tx),
1229                           (unsigned int)TICKS_TO_CYCLES(tx),
1230                           (unsigned int)TICKS_TO_OFFSET(tx));
1231
1232     return scheduleStateTransition(ePS_Stopped, tx);
1233 }
1234
1235 bool StreamProcessor::scheduleStopRunning(int64_t t) {
1236     uint64_t tx;
1237     if (t < 0) {
1238         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1239     } else {
1240         tx = t;
1241     }
1242     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1243     uint64_t now = m_1394service.getCycleTimerTicks();
1244     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1245                           now,
1246                           (unsigned int)TICKS_TO_SECS(now),
1247                           (unsigned int)TICKS_TO_CYCLES(now),
1248                           (unsigned int)TICKS_TO_OFFSET(now));
1249     debugOutput(DEBUG_LEVEL_VERBOSE,"  Stop at               : %011llu (%03us %04uc %04ut)\n",
1250                           tx,
1251                           (unsigned int)TICKS_TO_SECS(tx),
1252                           (unsigned int)TICKS_TO_CYCLES(tx),
1253                           (unsigned int)TICKS_TO_OFFSET(tx));
1254     return scheduleStateTransition(ePS_WaitingForStreamDisable, tx);
1255 }
1256
1257 bool StreamProcessor::startDryRunning(int64_t t) {
1258     if(!scheduleStartDryRunning(t)) {
1259         debugError("Could not schedule transition\n");
1260         return false;
1261     }
1262     if(!waitForState(ePS_DryRunning, 2000)) {
1263         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_DryRunning));
1264         return false;
1265     }
1266     return true;
1267 }
1268
1269 bool StreamProcessor::startRunning(int64_t t) {
1270     if(!scheduleStartRunning(t)) {
1271         debugError("Could not schedule transition\n");
1272         return false;
1273     }
1274     if(!waitForState(ePS_Running, 2000)) {
1275         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_Running));
1276         return false;
1277     }
1278     return true;
1279 }
1280
1281 bool StreamProcessor::stopDryRunning(int64_t t) {
1282     if(!scheduleStopDryRunning(t)) {
1283         debugError("Could not schedule transition\n");
1284         return false;
1285     }
1286     if(!waitForState(ePS_Stopped, 2000)) {
1287         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_Stopped));
1288         return false;
1289     }
1290     return true;
1291 }
1292
1293 bool StreamProcessor::stopRunning(int64_t t) {
1294     if(!scheduleStopRunning(t)) {
1295         debugError("Could not schedule transition\n");
1296         return false;
1297     }
1298     if(!waitForState(ePS_DryRunning, 2000)) {
1299         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_DryRunning));
1300         return false;
1301     }
1302     return true;
1303 }
1304
1305
1306 // internal state API
1307
1308 /**
1309  * @brief Enter the ePS_Stopped state
1310  * @return true if successful, false if not
1311  *
1312  * @pre none
1313  *
1314  * @post the buffer and the isostream are ready for use.
1315  * @post all dynamic structures have been allocated successfully
1316  * @post the buffer is transparent and empty, and all parameters are set
1317  *       to the correct initial/nominal values.
1318  *
1319  */
1320 bool
1321 StreamProcessor::doStop()
1322 {
1323     float ticks_per_frame;
1324     unsigned int ringbuffer_size_frames = (m_StreamProcessorManager.getNbBuffers() + 1) * m_StreamProcessorManager.getPeriodSize();
1325
1326     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1327     bool result = true;
1328
1329     switch(m_state) {
1330         case ePS_Created:
1331             assert(m_data_buffer);
1332
1333             // prepare the framerate estimate
1334             ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_StreamProcessorManager.getNominalRate());
1335             m_ticks_per_frame = ticks_per_frame;
1336             m_local_node_id= m_1394service.getLocalNodeId() & 0x3f;
1337             m_correct_last_timestamp = false;
1338
1339             debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame);
1340
1341             // initialize internal buffer
1342             result &= m_data_buffer->setBufferSize(ringbuffer_size_frames);
1343
1344             result &= m_data_buffer->setEventSize( getEventSize() );
1345             result &= m_data_buffer->setEventsPerFrame( getEventsPerFrame() );
1346             if(getType() == ePT_Receive) {
1347                 result &= m_data_buffer->setUpdatePeriod( getNominalFramesPerPacket() );
1348             } else {
1349                 result &= m_data_buffer->setUpdatePeriod( m_StreamProcessorManager.getPeriodSize() );
1350             }
1351             result &= m_data_buffer->setNominalRate(ticks_per_frame);
1352             result &= m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
1353             result &= m_data_buffer->prepare(); // FIXME: the name
1354
1355             break;
1356         case ePS_DryRunning:
1357             if(!m_IsoHandlerManager.stopHandlerForStream(this)) {
1358                 debugError("Could not stop handler for SP %p\n", this);
1359                 return false;
1360             }
1361             break;
1362         default:
1363             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1364             return false;
1365     }
1366
1367     result &= m_data_buffer->clearBuffer(); // FIXME: don't like the reset() name
1368     // make the buffer transparent
1369     m_data_buffer->setTransparent(true);
1370
1371     // reset all ports
1372     result &= PortManager::preparePorts();
1373
1374     m_state = ePS_Stopped;
1375     #ifdef DEBUG
1376     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1377         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1378         dumpInfo();
1379     }
1380     #endif
1381     return result;
1382 }
1383
1384 /**
1385  * @brief Enter the ePS_WaitingForStream state
1386  * @return true if successful, false if not
1387  *
1388  * @pre all dynamic data structures are allocated successfully
1389  *
1390  * @post
1391  *
1392  */
1393 bool
1394 StreamProcessor::doWaitForRunningStream()
1395 {
1396     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1397     switch(m_state) {
1398         case ePS_Stopped:
1399             // we have to start waiting for an incoming stream
1400             // this basically means nothing, the state change will
1401             // be picked up by the packet iterator
1402             break;
1403         default:
1404             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1405             return false;
1406     }
1407     m_state = ePS_WaitingForStream;
1408     #ifdef DEBUG
1409     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1410         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1411         dumpInfo();
1412     }
1413     #endif
1414     return true;
1415 }
1416
1417 /**
1418  * @brief Enter the ePS_DryRunning state
1419  * @return true if successful, false if not
1420  *
1421  * @pre
1422  *
1423  * @post
1424  *
1425  */
1426 bool
1427 StreamProcessor::doDryRunning()
1428 {
1429     bool result = true;
1430     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1431     switch(m_state) {
1432         case ePS_WaitingForStream:
1433             // a running stream has been detected
1434             debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started dry-running at cycle %d\n", this, m_last_cycle);
1435             m_local_node_id = m_1394service.getLocalNodeId() & 0x3f;
1436             if (getType() == ePT_Receive) {
1437                 // this to ensure that there is no discontinuity when starting to
1438                 // update the DLL based upon the received packets
1439                 m_data_buffer->setBufferTailTimestamp(m_last_timestamp);
1440             } else {
1441                 // FIXME: PC=master mode will have to do something here I guess...
1442             }
1443             break;
1444         case ePS_WaitingForStreamEnable: // when xrunning at startup
1445             result &= m_data_buffer->clearBuffer();
1446             m_data_buffer->setTransparent(true);
1447             break;
1448         case ePS_WaitingForStreamDisable:
1449             result &= m_data_buffer->clearBuffer();
1450             m_data_buffer->setTransparent(true);
1451             break;
1452         default:
1453             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1454             return false;
1455     }
1456     m_state = ePS_DryRunning;
1457     #ifdef DEBUG
1458     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1459         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1460         dumpInfo();
1461     }
1462     #endif
1463     return result;
1464 }
1465
1466 /**
1467  * @brief Enter the ePS_WaitingForStreamEnable state
1468  * @return true if successful, false if not
1469  *
1470  * @pre
1471  *
1472  * @post
1473  *
1474  */
1475 bool
1476 StreamProcessor::doWaitForStreamEnable()
1477 {
1478     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1479     unsigned int ringbuffer_size_frames;
1480     switch(m_state) {
1481         case ePS_DryRunning:
1482             // we have to start waiting for an incoming stream
1483             // this basically means nothing, the state change will
1484             // be picked up by the packet iterator
1485
1486             sem_init(&m_signal_semaphore, 0, 0);
1487             m_signal_period = m_StreamProcessorManager.getPeriodSize();
1488             m_signal_offset = 0; // FIXME: we have to ensure that everyone is ready
1489
1490             if(!m_data_buffer->clearBuffer()) {
1491                 debugError("Could not reset data buffer\n");
1492                 return false;
1493             }
1494             if (getType() == ePT_Transmit) {
1495                 ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize();
1496                 debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames\n", this, ringbuffer_size_frames);
1497                 // prefill the buffer
1498                 if(!transferSilence(ringbuffer_size_frames)) {
1499                     debugFatal("Could not prefill transmit stream\n");
1500                     return false;
1501                 }
1502                 if (m_data_buffer->getBufferFill() >= m_signal_period + m_signal_offset) {
1503                     POST_SEMAPHORE;
1504                 }
1505             }
1506
1507             break;
1508         default:
1509             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1510             return false;
1511     }
1512     m_state = ePS_WaitingForStreamEnable;
1513     #ifdef DEBUG
1514     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1515         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1516         dumpInfo();
1517     }
1518     #endif
1519     return true;
1520 }
1521
1522 /**
1523  * @brief Enter the ePS_Running state
1524  * @return true if successful, false if not
1525  *
1526  * @pre
1527  *
1528  * @post
1529  *
1530  */
1531 bool
1532 StreamProcessor::doRunning()
1533 {
1534     bool result = true;
1535     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1536     switch(m_state) {
1537         case ePS_WaitingForStreamEnable:
1538             // a running stream has been detected
1539             debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started running at cycle %d\n",
1540                                              this, m_last_cycle);
1541             m_in_xrun = false;
1542             m_local_node_id = m_1394service.getLocalNodeId() & 0x3f;
1543             m_data_buffer->setTransparent(false);
1544             break;
1545         default:
1546             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1547             return false;
1548     }
1549     m_state = ePS_Running;
1550     #ifdef DEBUG
1551     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1552         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1553         dumpInfo();
1554     }
1555     #endif
1556     return result;
1557 }
1558
1559 /**
1560  * @brief Enter the ePS_WaitingForStreamDisable state
1561  * @return true if successful, false if not
1562  *
1563  * @pre
1564  *
1565  * @post
1566  *
1567  */
1568 bool
1569 StreamProcessor::doWaitForStreamDisable()
1570 {
1571     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1572     switch(m_state) {
1573         case ePS_Running:
1574             // the thread will do the transition
1575
1576             // we have to wake the iterator if it's asleep
1577             POST_SEMAPHORE;
1578             break;
1579         default:
1580             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1581             return false;
1582     }
1583     m_state = ePS_WaitingForStreamDisable;
1584     #ifdef DEBUG
1585     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1586         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1587         dumpInfo();
1588     }
1589     #endif
1590     return true;
1591 }
1592
1593 /**
1594  * @brief Updates the state machine and calls the necessary transition functions
1595  * @return true if successful, false if not
1596  */
1597 bool StreamProcessor::updateState() {
1598     bool result = false;
1599     // copy the current state locally since it could change value,
1600     // and that's something we don't want to happen inbetween tests
1601     // if m_next_state changes during this routine, we know for sure
1602     // that the previous state change was at least attempted correctly.
1603     enum eProcessorState next_state = m_next_state;
1604
1605     debugOutput(DEBUG_LEVEL_VERBOSE, "Do state transition: %s => %s\n",
1606         ePSToString(m_state), ePSToString(next_state));
1607
1608     if (m_state == next_state) {
1609         debugWarning("ignoring identity state update from/to %s\n", ePSToString(m_state) );
1610         return true;
1611     }
1612
1613     // after creation, only initialization is allowed
1614     if (m_state == ePS_Created) {
1615         if(next_state != ePS_Stopped) {
1616             goto updateState_exit_with_error;
1617         }
1618         // do init here
1619         result = doStop();
1620         if (result) {POST_SEMAPHORE; return true;}
1621         else goto updateState_exit_change_failed;
1622     }
1623
1624     // after initialization, only WaitingForRunningStream is allowed
1625     if (m_state == ePS_Stopped) {
1626         if(next_state != ePS_WaitingForStream) {
1627             goto updateState_exit_with_error;
1628         }
1629         result = doWaitForRunningStream();
1630         if (result) {POST_SEMAPHORE; return true;}
1631         else goto updateState_exit_change_failed;
1632     }
1633
1634     // after WaitingForStream, only ePS_DryRunning is allowed
1635     // this means that the stream started running
1636     if (m_state == ePS_WaitingForStream) {
1637         if(next_state != ePS_DryRunning) {
1638             goto updateState_exit_with_error;
1639         }
1640         result = doDryRunning();
1641         if (result) {POST_SEMAPHORE; return true;}
1642         else goto updateState_exit_change_failed;
1643     }
1644
1645     // from ePS_DryRunning we can go to:
1646     //   - ePS_Stopped if something went wrong during DryRunning
1647     //   - ePS_WaitingForStreamEnable if there is a requested to enable
1648     if (m_state == ePS_DryRunning) {
1649         if((next_state != ePS_Stopped) &&
1650            (next_state != ePS_WaitingForStreamEnable)) {
1651             goto updateState_exit_with_error;
1652         }
1653         if (next_state == ePS_Stopped) {
1654             result = doStop();
1655         } else {
1656             result = doWaitForStreamEnable();
1657         }
1658         if (result) {POST_SEMAPHORE; return true;}
1659         else goto updateState_exit_change_failed;
1660     }
1661
1662     // from ePS_WaitingForStreamEnable we can go to:
1663     //   - ePS_DryRunning if something went wrong while waiting
1664     //   - ePS_Running if the stream enabled correctly
1665     if (m_state == ePS_WaitingForStreamEnable) {
1666         if((next_state != ePS_DryRunning) &&
1667            (next_state != ePS_Running)) {
1668             goto updateState_exit_with_error;
1669         }
1670         if (next_state == ePS_Stopped) {
1671             result = doDryRunning();
1672         } else {
1673             result = doRunning();
1674         }
1675         if (result) {POST_SEMAPHORE; return true;}
1676         else goto updateState_exit_change_failed;
1677     }
1678
1679     // from ePS_Running we can only start waiting for a disabled stream
1680     if (m_state == ePS_Running) {
1681         if(next_state != ePS_WaitingForStreamDisable) {
1682             goto updateState_exit_with_error;
1683         }
1684         result = doWaitForStreamDisable();
1685         if (result) {POST_SEMAPHORE; return true;}
1686         else goto updateState_exit_change_failed;
1687     }
1688
1689     // from ePS_WaitingForStreamDisable we can go to DryRunning
1690     if (m_state == ePS_WaitingForStreamDisable) {
1691         if(next_state != ePS_DryRunning) {
1692             goto updateState_exit_with_error;
1693         }
1694         result = doDryRunning();
1695         if (result) {POST_SEMAPHORE; return true;}
1696         else goto updateState_exit_change_failed;
1697     }
1698
1699     // if we arrive here there is an error
1700 updateState_exit_with_error:
1701     debugError("Invalid state transition: %s => %s\n",
1702         ePSToString(m_state), ePSToString(next_state));
1703     POST_SEMAPHORE;
1704     return false;
1705 updateState_exit_change_failed:
1706     debugError("State transition failed: %s => %s\n",
1707         ePSToString(m_state), ePSToString(next_state));
1708     POST_SEMAPHORE;
1709     return false;
1710 }
1711
1712 /***********************************************
1713  * Helper routines                             *
1714  ***********************************************/
1715 bool
1716 StreamProcessor::transferSilence(unsigned int nframes)
1717 {
1718     bool retval;
1719     signed int fc;
1720     ffado_timestamp_t ts_tail_tmp;
1721
1722     // prepare a buffer of silence
1723     char *dummybuffer = (char *)calloc(getEventSize(), nframes * getEventsPerFrame());
1724     transmitSilenceBlock(dummybuffer, nframes, 0);
1725
1726     m_data_buffer->getBufferTailTimestamp(&ts_tail_tmp, &fc);
1727     if (fc != 0) {
1728         debugWarning("Prefilling a buffer that already contains %d frames\n", fc);
1729     }
1730
1731     // add the silence data to the ringbuffer
1732     if(m_data_buffer->preloadFrames(nframes, dummybuffer, true)) {
1733         retval = true;
1734     } else {
1735         debugWarning("Could not write to event buffer\n");
1736         retval = false;
1737     }
1738     free(dummybuffer);
1739     return retval;
1740 }
1741
1742 /**
1743  * @brief convert a eProcessorState to a string
1744  * @param s the state
1745  * @return a char * describing the state
1746  */
1747 const char *
1748 StreamProcessor::ePSToString(enum eProcessorState s) {
1749     switch (s) {
1750         case ePS_Invalid: return "ePS_Invalid";
1751         case ePS_Created: return "ePS_Created";
1752         case ePS_Stopped: return "ePS_Stopped";
1753         case ePS_WaitingForStream: return "ePS_WaitingForStream";
1754         case ePS_DryRunning: return "ePS_DryRunning";
1755         case ePS_WaitingForStreamEnable: return "ePS_WaitingForStreamEnable";
1756         case ePS_Running: return "ePS_Running";
1757         case ePS_WaitingForStreamDisable: return "ePS_WaitingForStreamDisable";
1758         default: return "error: unknown state";
1759     }
1760 }
1761
1762 /**
1763  * @brief convert a eProcessorType to a string
1764  * @param t the type
1765  * @return a char * describing the state
1766  */
1767 const char *
1768 StreamProcessor::ePTToString(enum eProcessorType t) {
1769     switch (t) {
1770         case ePT_Receive: return "Receive";
1771         case ePT_Transmit: return "Transmit";
1772         default: return "error: unknown type";
1773     }
1774 }
1775
1776 /***********************************************
1777  * Debug                                       *
1778  ***********************************************/
1779 void
1780 StreamProcessor::dumpInfo()
1781 {
1782     debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor %p, %s:\n", this, ePTToString(m_processor_type));
1783     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel  : %d, %d\n", m_1394service.getPort(), m_channel);
1784     uint64_t now = m_1394service.getCycleTimerTicks();
1785     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011llu (%03us %04uc %04ut)\n",
1786                         now,
1787                         (unsigned int)TICKS_TO_SECS(now),
1788                         (unsigned int)TICKS_TO_CYCLES(now),
1789                         (unsigned int)TICKS_TO_OFFSET(now));
1790     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xrun?                 : %s\n", (m_in_xrun ? "True":"False"));
1791     if (m_state == m_next_state) {
1792         debugOutputShort( DEBUG_LEVEL_NORMAL, "  State                 : %s\n",
1793                                             ePSToString(m_state));
1794     } else {
1795         debugOutputShort( DEBUG_LEVEL_NORMAL, "  State                 : %s (Next: %s)\n",
1796                                               ePSToString(m_state), ePSToString(m_next_state));
1797         debugOutputShort( DEBUG_LEVEL_NORMAL, "    transition at       : %u\n", m_cycle_to_switch_state);
1798     }
1799     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer                : %p\n", m_data_buffer);
1800     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Framerate             : Nominal: %u, Sync: %f, Buffer %f\n",
1801                                           m_StreamProcessorManager.getNominalRate(),
1802                                           24576000.0/m_StreamProcessorManager.getSyncSource().m_data_buffer->getRate(),
1803                                           24576000.0/m_data_buffer->getRate());
1804     float d = getSyncDelay();
1805     debugOutputShort(DEBUG_LEVEL_NORMAL, "  Sync delay             : %f ticks (%f frames, %f cy)\n",
1806                                          d, d/getTicksPerFrame(),
1807                                          d/((float)TICKS_PER_CYCLE));
1808     m_data_buffer->dumpInfo();
1809 }
1810
1811 void
1812 StreamProcessor::setVerboseLevel(int l) {
1813     setDebugLevel(l);
1814     PortManager::setVerboseLevel(l);
1815     m_data_buffer->setVerboseLevel(l);
1816 }
1817
1818 } // end of namespace
Note: See TracBrowser for help on using the browser.