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

Revision 2803, 75.3 kB (checked in by jwoithe, 3 years ago)

Cosmetic: capitalise "L" in "Linux".

"Linux" is a proper noun so it should start with a capital letter. These
changes are almost all within comments.

This patch was originally proposed by pander on the ffado-devel mailing
list. It has been expanded to cover all similar cases to maintain
consistency throughout the source tree.

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