root/branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.cpp

Revision 1346, 71.3 kB (checked in by ppalmers, 15 years ago)

add one syncdelay worth of frames to the roundtrip loop. this should allow to use only 2 buffers instead of 3

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