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

Revision 857, 70.0 kB (checked in by ppalmers, 13 years ago)

Introduce distinction between empty and silent packets. When shutting down a transmit SP, we now send silent (= valid, but all audio muted) packets instead of empty (w/o
payload) packets for a while. This should solve the shutdown issue with the motu's.

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