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

Revision 1032, 66.9 kB (checked in by ppalmers, 16 years ago)

some more shuffling. Eliminate the CTR read from the generic transmit SP.

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