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

Revision 1344, 71.0 kB (checked in by ppalmers, 15 years ago)

switch back to a sleep based period signalling scheme to ensure proper wakeup timing

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