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

Revision 841, 69.1 kB (checked in by ppalmers, 14 years ago)

fix single ISO thread operation (1394 stack seems to be thread-unsafe)

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                     unsigned int signal_period = m_signal_period * (semval + 1) + m_signal_offset;
475                     if(bufferfill >= signal_period) {
476                         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) buffer fill (%d) > signal period (%d), sem_val=%d\n",
477                                     this, m_data_buffer->getBufferFill(), signal_period, semval);
478                         POST_SEMAPHORE;
479                     }
480                     // the process thread should have higher prio such that we are blocked until
481                     // the samples are processed.
482                     return RAW1394_ISO_DEFER;
483                 }
484             }
485             return RAW1394_ISO_OK;
486         } else {
487             debugError("Invalid response\n");
488             POST_SEMAPHORE;
489             return RAW1394_ISO_ERROR;
490         }
491     } else if(result == eCRV_Invalid) {
492         // apparently we don't have to do anything when the packets are not valid
493         return RAW1394_ISO_OK;
494     } else {
495         debugError("Invalid response\n");
496         POST_SEMAPHORE;
497         return RAW1394_ISO_ERROR;
498     }
499     debugError("reached the unreachable\n");
500     POST_SEMAPHORE;
501     return RAW1394_ISO_ERROR;
502 }
503
504 enum raw1394_iso_disposition
505 StreamProcessor::getPacket(unsigned char *data, unsigned int *length,
506                            unsigned char *tag, unsigned char *sy,
507                            int cycle, unsigned int dropped, unsigned int max_length) {
508     if (cycle<0) {
509         *tag = 0;
510         *sy = 0;
511         *length = 0;
512         return RAW1394_ISO_OK;
513     }
514
515     unsigned int ctr;
516     int now_cycles;
517     int cycle_diff;
518
519 #ifdef DEBUG
520     if(m_last_cycle == -1) {
521         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle);
522     }
523 #endif
524
525     int dropped_cycles = 0;
526     if (m_last_cycle != cycle && m_last_cycle != -1) {
527         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
528         if (dropped_cycles < 0) {
529             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",
530                          this, dropped_cycles, cycle, m_last_cycle, dropped);
531         }
532         if (dropped_cycles > 0) {
533             debugWarning("(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d)\n", this, dropped_cycles, cycle, m_last_cycle, dropped);
534             m_dropped += dropped_cycles;
535             // HACK: this should not be necessary, since the header generation functions should trigger the xrun.
536             //       but apparently there are some issues with the 1394 stack
537             m_in_xrun = true;
538             if(m_state == ePS_Running) {
539                 debugShowBackLogLines(200);
540                 debugWarning("dropped packets xrun\n");
541                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packets xrun\n");
542                 m_cycle_to_switch_state = cycle + 1;
543                 m_next_state = ePS_WaitingForStreamDisable;
544                 // execute the requested change
545                 if (!updateState()) { // we are allowed to change the state directly
546                     debugError("Could not update state!\n");
547                     return RAW1394_ISO_ERROR;
548                 }
549                 goto send_empty_packet;
550             }
551         }
552     }
553     if (cycle >= 0) {
554         m_last_cycle = cycle;
555     }
556
557 #ifdef DEBUG
558     // bypass based upon state
559     if (m_state == ePS_Invalid) {
560         debugError("Should not have state %s\n", ePSToString(m_state) );
561         return RAW1394_ISO_ERROR;
562     }
563 #endif
564
565     if (m_state == ePS_Created) {
566         *tag = 0;
567         *sy = 0;
568         *length = 0;
569         return RAW1394_ISO_DEFER;
570     }
571
572     // normal processing
573     // note that we can't use getCycleTimer directly here,
574     // because packets are queued in advance. This means that
575     // we the packet we are constructing will be sent out
576     // on 'cycle', not 'now'.
577     ctr = m_1394service.getCycleTimer();
578     now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
579
580     // the difference between the cycle this
581     // packet is intended for and 'now'
582     cycle_diff = diffCycles(cycle, now_cycles);
583
584     if(cycle_diff < 0 && (m_state == ePS_Running || m_state == ePS_DryRunning)) {
585         debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n",
586             cycle, now_cycles);
587         if(m_state == ePS_Running) {
588             debugShowBackLogLines(200);
589 //             flushDebugOutput();
590 //             assert(0);
591             debugWarning("generatePacketData xrun\n");
592             m_in_xrun = true;
593             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n");
594             m_cycle_to_switch_state = cycle + 1;
595             m_next_state = ePS_WaitingForStreamDisable;
596             // execute the requested change
597             if (!updateState()) { // we are allowed to change the state directly
598                 debugError("Could not update state!\n");
599                 return RAW1394_ISO_ERROR;
600             }
601             goto send_empty_packet;
602         }
603     }
604
605     // store the previous timestamp
606     m_last_timestamp2 = m_last_timestamp;
607
608     // NOTE: synchronized switching is restricted to a 0.5 sec span (4000 cycles)
609     //       it happens on the first 'good' cycle for the wait condition
610     //       or on the first received cycle that is received afterwards (might be a problem)
611
612     // check whether we are waiting for a stream to be disabled
613     if(m_state == ePS_WaitingForStreamDisable) {
614         // we then check whether we have to switch on this cycle
615         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
616             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning\n");
617             m_next_state = ePS_DryRunning;
618             if (!updateState()) { // we are allowed to change the state directly
619                 debugError("Could not update state!\n");
620                 return RAW1394_ISO_ERROR;
621             }
622         } else {
623             // not time to disable yet
624         }
625     }
626     // check whether we are waiting for a stream to be enabled
627     else if(m_state == ePS_WaitingForStreamEnable) {
628         // we then check whether we have to switch on this cycle
629         if (diffCycles(cycle, m_cycle_to_switch_state) >= 0) {
630             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to Running\n");
631             m_next_state = ePS_Running;
632             if (!updateState()) { // we are allowed to change the state directly
633                 debugError("Could not update state!\n");
634                 return RAW1394_ISO_ERROR;
635             }
636         } else {
637             // not time to enable yet
638         }
639         // we are dryRunning hence data should be processed in any case
640     }
641     // check whether we are waiting for a stream to startup
642     else if(m_state == ePS_WaitingForStream) {
643         // as long as the cycle parameter is not in sync with
644         // the current time, the stream is considered not
645         // to be 'running'
646         // we then check whether we have to switch on this cycle
647         if ((cycle_diff >= 0) && (diffCycles(cycle, m_cycle_to_switch_state) >= 0)) {
648             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStream to DryRunning\n");
649             // hence go to the dryRunning state
650             m_next_state = ePS_DryRunning;
651             if (!updateState()) { // we are allowed to change the state directly
652                 debugError("Could not update state!\n");
653                 return RAW1394_ISO_ERROR;
654             }
655         } else {
656             // not time (yet) to switch state
657         }
658     }
659     else if(m_state == ePS_Running) {
660         // check the packet header
661         enum eChildReturnValue result = generatePacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
662         if (result == eCRV_Packet || result == eCRV_Defer) {
663             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT: CY=%04u TS=%011llu\n",
664                     cycle, m_last_timestamp);
665             // update some accounting
666             m_last_good_cycle = cycle;
667             m_last_dropped = dropped_cycles;
668
669             // check whether a state change has been requested
670             // note that only the wait state changes are synchronized with the cycles
671             if(m_state != m_next_state) {
672                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
673                                                 ePSToString(m_state), ePSToString(m_next_state));
674                 // execute the requested change
675                 if (!updateState()) { // we are allowed to change the state directly
676                     debugError("Could not update state!\n");
677                     return RAW1394_ISO_ERROR;
678                 }
679             }
680
681             enum eChildReturnValue result2 = generatePacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
682             // if an xrun occured, switch to the dryRunning state and
683             // allow for the xrun to be picked up
684             if (result2 == eCRV_XRun) {
685                 debugWarning("generatePacketData xrun\n");
686                 m_in_xrun = true;
687                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n");
688                 m_cycle_to_switch_state = cycle + 1; // switch in the next cycle
689                 m_next_state = ePS_WaitingForStreamDisable;
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                 goto send_empty_packet;
696             }
697             // skip queueing packets if we detect that there are not enough frames
698             // available
699             if(result2 == eCRV_Defer || result == eCRV_Defer)
700                 return RAW1394_ISO_DEFER;
701             else
702                 return RAW1394_ISO_OK;
703         } else if (result == eCRV_XRun) { // pick up the possible xruns
704             debugWarning("generatePacketHeader xrun\n");
705             m_in_xrun = true;
706             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n");
707             m_cycle_to_switch_state = cycle + 1; // switch in the next cycle
708             m_next_state = ePS_WaitingForStreamDisable;
709             // execute the requested change
710             if (!updateState()) { // we are allowed to change the state directly
711                 debugError("Could not update state!\n");
712                 return RAW1394_ISO_ERROR;
713             }
714         } else if (result == eCRV_EmptyPacket) {
715             if(m_state != m_next_state) {
716                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
717                                                 ePSToString(m_state), ePSToString(m_next_state));
718                 // execute the requested change
719                 if (!updateState()) { // we are allowed to change the state directly
720                     debugError("Could not update state!\n");
721                     return RAW1394_ISO_ERROR;
722                 }
723             }
724             goto send_empty_packet;
725         } else if (result == eCRV_Again) {
726             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle);
727             if(m_state != m_next_state) {
728                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
729                                                 ePSToString(m_state), ePSToString(m_next_state));
730                 // execute the requested change
731                 if (!updateState()) { // we are allowed to change the state directly
732                     debugError("Could not update state!\n");
733                     return RAW1394_ISO_ERROR;
734                 }
735             }
736             usleep(125); // only when using thread-per-handler
737             return RAW1394_ISO_AGAIN;
738 //             generateSilentPacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
739 //             generateSilentPacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
740 //             return RAW1394_ISO_DEFER;
741         } else {
742             debugError("Invalid return value: %d\n", result);
743             return RAW1394_ISO_ERROR;
744         }
745     }
746     // we are not running, so send an empty packet
747     // we should generate a valid packet any time
748 send_empty_packet:
749     // note that only the wait state changes are synchronized with the cycles
750     if(m_state != m_next_state) {
751         debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n",
752                                         ePSToString(m_state), ePSToString(m_next_state));
753         // execute the requested change
754         if (!updateState()) { // we are allowed to change the state directly
755             debugError("Could not update state!\n");
756             return RAW1394_ISO_ERROR;
757         }
758     }
759
760     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT EMPTY: CY=%04u\n", cycle);
761     generateSilentPacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length);
762     generateSilentPacketData(data, length, tag, sy, cycle, dropped_cycles, max_length);
763     return RAW1394_ISO_OK;
764 }
765
766
767 // Frame Transfer API
768 /**
769  * Transfer a block of frames from the event buffer to the port buffers
770  * @param nbframes number of frames to transfer
771  * @param ts the timestamp that the LAST frame in the block should have
772  * @return
773  */
774 bool StreamProcessor::getFrames(unsigned int nbframes, int64_t ts) {
775     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p.getFrames(%d, %11llu)", nbframes, ts);
776     assert( getType() == ePT_Receive );
777     if(isDryRunning()) return getFramesDry(nbframes, ts);
778     else return getFramesWet(nbframes, ts);
779 }
780
781 bool StreamProcessor::getFramesWet(unsigned int nbframes, int64_t ts) {
782 // FIXME: this should be done somewhere else
783 #ifdef DEBUG
784     uint64_t ts_expected;
785     signed int fc;
786     int32_t lag_ticks;
787     float lag_frames;
788
789     // in order to sync up multiple received streams, we should
790     // use the ts parameter. It specifies the time of the block's
791     // last sample.
792     float srate = m_StreamProcessorManager.getSyncSource().getTicksPerFrame();
793     assert(srate != 0.0);
794     int64_t this_block_length_in_ticks = (int64_t)(((float)nbframes) * srate);
795
796     ffado_timestamp_t ts_head_tmp;
797     m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc);
798     ts_expected = addTicks((uint64_t)ts_head_tmp, this_block_length_in_ticks);
799
800     lag_ticks = diffTicks(ts, ts_expected);
801     lag_frames = (((float)lag_ticks) / srate);
802     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): drifts %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
803                  this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
804     if (lag_frames >= 1.0) {
805         // the stream lags
806         debugWarning( "stream (%p): lags  with %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
807                       this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
808     } else if (lag_frames <= -1.0) {
809         // the stream leads
810         debugWarning( "stream (%p): leads with %6d ticks = %10.5f frames (rate=%10.5f), %lld, %llu, %d\n",
811                       this, lag_ticks, lag_frames, srate, ts, ts_expected, fc);
812     }
813 #endif
814     // ask the buffer to process nbframes of frames
815     // using it's registered client's processReadBlock(),
816     // which should be ours
817     m_data_buffer->blockProcessReadFrames(nbframes);
818     return true;
819 }
820
821 bool StreamProcessor::getFramesDry(unsigned int nbframes, int64_t ts)
822 {
823     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): dry run %d frames (@ ts=%lld)\n",
824                  this, nbframes, ts);
825     // dry run on this side means that we put silence in all enabled ports
826     // since there is do data put into the ringbuffer in the dry-running state
827     return provideSilenceBlock(nbframes, 0);
828 }
829
830 bool
831 StreamProcessor::dropFrames(unsigned int nbframes, int64_t ts)
832 {
833     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "StreamProcessor::dropFrames(%d, %lld)\n", nbframes, ts);
834     return m_data_buffer->dropFrames(nbframes);
835 }
836
837 bool StreamProcessor::putFrames(unsigned int nbframes, int64_t ts)
838 {
839     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p.putFrames(%d, %11llu)", nbframes, ts);
840     assert( getType() == ePT_Transmit );
841
842     if(isDryRunning()) return putFramesDry(nbframes, ts);
843     else return putFramesWet(nbframes, ts);
844 }
845
846 bool
847 StreamProcessor::putFramesWet(unsigned int nbframes, int64_t ts)
848 {
849     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putFramesWet(%d, %llu)\n", nbframes, ts);
850     // transfer the data
851     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
852     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
853
854     unsigned int bufferfill = m_data_buffer->getBufferFill();
855     if (bufferfill >= m_signal_period + m_signal_offset) {
856         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n",
857                                          this, bufferfill, m_signal_period + m_signal_offset);
858         POST_SEMAPHORE;
859     } else {
860         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n",
861                                          this, bufferfill, m_signal_period + m_signal_offset);
862     }
863     return true; // FIXME: what about failure?
864 }
865
866 bool
867 StreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts)
868 {
869     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts);
870     // do nothing
871     return true;
872 }
873
874 bool
875 StreamProcessor::putSilenceFrames(unsigned int nbframes, int64_t ts)
876 {
877     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "StreamProcessor::putSilenceFrames(%d, %llu)\n", nbframes, ts);
878
879     size_t bytes_per_frame = getEventSize() * getEventsPerFrame();
880     unsigned int scratch_buffer_size_frames = m_scratch_buffer_size_bytes / bytes_per_frame;
881
882     if (nbframes > scratch_buffer_size_frames) {
883         debugError("nframes (%u) > scratch_buffer_size_frames (%u)\n",
884                    nbframes, scratch_buffer_size_frames);
885     }
886
887     assert(m_scratch_buffer);
888     if(!transmitSilenceBlock((char *)m_scratch_buffer, nbframes, 0)) {
889         debugError("Could not prepare silent block\n");
890         return false;
891     }
892     if(!m_data_buffer->writeFrames(nbframes, (char *)m_scratch_buffer, ts)) {
893         debugError("Could not write silent block\n");
894         return false;
895     }
896
897     unsigned int bufferfill = m_data_buffer->getBufferFill();
898     if (bufferfill >= m_signal_period + m_signal_offset) {
899         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n",
900                                          this, bufferfill, m_signal_period + m_signal_offset);
901         POST_SEMAPHORE;
902     } else {
903         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n",
904                                          this, bufferfill, m_signal_period + m_signal_offset);
905     }
906
907     return true;
908 }
909
910 bool
911 StreamProcessor::waitForSignal()
912 {
913     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) wait ...\n", this, getTypeString());
914     int result;
915     if(m_state == ePS_Running && m_next_state == ePS_Running) {
916         // check whether we already fullfil the criterion
917         unsigned int bufferfill = m_data_buffer->getBufferFill();
918         if(bufferfill >= m_signal_period + m_signal_offset) {
919             return true;
920         }
921
922         result = sem_wait(&m_signal_semaphore);
923 #ifdef DEBUG
924         int tmp;
925         sem_getvalue(&m_signal_semaphore, &tmp);
926         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp);
927 #endif
928         return result == 0;
929     } else {
930         // when we're not running, we can always provide frames
931         // when we're in a state transition, keep iterating too
932         debugOutput(DEBUG_LEVEL_VERBOSE, "Not running...\n");
933         return true;
934     }
935 }
936
937 bool
938 StreamProcessor::tryWaitForSignal()
939 {
940     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) trywait ...\n", this, getTypeString());
941     int result;
942     if(m_state == ePS_Running && m_next_state == ePS_Running) {
943         // check whether we already fullfil the criterion
944         unsigned int bufferfill = m_data_buffer->getBufferFill();
945         if(bufferfill >= m_signal_period + m_signal_offset) {
946             return true;
947         }
948
949         result = sem_trywait(&m_signal_semaphore);
950 #ifdef DEBUG
951         int tmp;
952         sem_getvalue(&m_signal_semaphore, &tmp);
953         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp);
954 #endif
955         return result == 0;
956     } else {
957         // when we're not running, we can always provide frames
958         // when we're in a state transition, keep iterating too
959         debugOutput(DEBUG_LEVEL_VERBOSE, "Not running...\n");
960         return true;
961     }
962 }
963
964 bool
965 StreamProcessor::canProcessPackets()
966 {
967     if(m_state != ePS_Running || m_next_state != ePS_Running) return true;
968     bool result;
969     unsigned int bufferfill;
970     if(getType() == ePT_Receive) {
971         bufferfill = m_data_buffer->getBufferSpace();
972     } else {
973         bufferfill = m_data_buffer->getBufferFill();
974     }
975     result = bufferfill > getNominalFramesPerPacket();
976 //     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) for a bufferfill of %d, we return %d\n",
977 //                 this, ePTToString(getType()), bufferfill, result);
978     return result;
979 }
980
981 bool
982 StreamProcessor::shiftStream(int nbframes)
983 {
984     if(nbframes == 0) return true;
985     if(nbframes > 0) {
986         return m_data_buffer->dropFrames(nbframes);
987     } else {
988         bool result = true;
989         while(nbframes++) {
990             result &= m_data_buffer->writeDummyFrame();
991         }
992         return result;
993     }
994 }
995
996 /**
997  * @brief write silence events to the stream ringbuffers.
998  */
999 bool StreamProcessor::provideSilenceBlock(unsigned int nevents, unsigned int offset)
1000 {
1001     bool no_problem=true;
1002     for ( PortVectorIterator it = m_Ports.begin();
1003           it != m_Ports.end();
1004           ++it ) {
1005         if((*it)->isDisabled()) {continue;};
1006
1007         if(provideSilenceToPort((*it), offset, nevents)) {
1008             debugWarning("Could not put silence into to port %s",(*it)->getName().c_str());
1009             no_problem=false;
1010         }
1011     }
1012     return no_problem;
1013 }
1014
1015 int
1016 StreamProcessor::provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents)
1017 {
1018     unsigned int j=0;
1019     switch(p->getPortType()) {
1020         default:
1021             debugError("Invalid port type: %d\n", p->getPortType());
1022             return -1;
1023         case Port::E_Midi:
1024         case Port::E_Control:
1025             {
1026                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1027                 assert(nevents + offset <= p->getBufferSize());
1028                 buffer+=offset;
1029
1030                 for(j = 0; j < nevents; j += 1) {
1031                     *(buffer)=0;
1032                     buffer++;
1033                 }
1034             }
1035             break;
1036         case Port::E_Audio:
1037             switch(m_StreamProcessorManager.getAudioDataType()) {
1038             case StreamProcessorManager::eADT_Int24:
1039                 {
1040                     quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1041                     assert(nevents + offset <= p->getBufferSize());
1042                     buffer+=offset;
1043    
1044                     for(j = 0; j < nevents; j += 1) {
1045                         *(buffer)=0;
1046                         buffer++;
1047                     }
1048                 }
1049                 break;
1050             case StreamProcessorManager::eADT_Float:
1051                 {
1052                     float *buffer=(float *)(p->getBufferAddress());
1053                     assert(nevents + offset <= p->getBufferSize());
1054                     buffer+=offset;
1055    
1056                     for(j = 0; j < nevents; j += 1) {
1057                         *buffer = 0.0;
1058                         buffer++;
1059                     }
1060                 }
1061                 break;
1062             }
1063             break;
1064     }
1065     return 0;
1066 }
1067
1068 /***********************************************
1069  * State related API                           *
1070  ***********************************************/
1071 bool StreamProcessor::init()
1072 {
1073     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "init...\n");
1074
1075     if (sem_init(&m_signal_semaphore, 0, 0) == -1) {
1076         debugError("Could not init signal semaphore");
1077         return false;
1078     }
1079
1080     if(!m_IsoHandlerManager.registerStream(this)) {
1081         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register stream processor with the Iso manager\n");
1082         return false;
1083     }
1084     if(!m_StreamProcessorManager.registerProcessor(this)) {
1085         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register stream processor with the SP manager\n");
1086         return false;
1087     }
1088
1089     // initialization can be done without requesting it
1090     // from the packet loop
1091     m_next_state = ePS_Created;
1092     return true;
1093 }
1094
1095 bool StreamProcessor::prepare()
1096 {
1097     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare SP (%p)...\n", this);
1098
1099     // make the scratch buffer one period of frames long
1100     m_scratch_buffer_size_bytes = m_StreamProcessorManager.getPeriodSize() * getEventsPerFrame() * getEventSize();
1101     debugOutput( DEBUG_LEVEL_VERBOSE, " Allocate scratch buffer of %d quadlets\n");
1102     if(m_scratch_buffer) delete[] m_scratch_buffer;
1103     m_scratch_buffer = new byte_t[m_scratch_buffer_size_bytes];
1104     if(m_scratch_buffer == NULL) {
1105         debugFatal("Could not allocate scratch buffer\n");
1106         return false;
1107     }
1108
1109     // set the parameters of ports we can:
1110     // we want the audio ports to be period buffered,
1111     // and the midi ports to be packet buffered
1112     for ( PortVectorIterator it = m_Ports.begin();
1113         it != m_Ports.end();
1114         ++it )
1115     {
1116         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1117         if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) {
1118             debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize());
1119             return false;
1120         }
1121     }
1122     // the API specific settings of the ports should already be set,
1123     // as this is called from the processorManager->prepare()
1124     // so we can init the ports
1125     if(!PortManager::initPorts()) {
1126         debugFatal("Could not initialize ports\n");
1127         return false;
1128     }
1129
1130     if (!prepareChild()) {
1131         debugFatal("Could not prepare child\n");
1132         return false;
1133     }
1134
1135     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
1136     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d\n",
1137              m_StreamProcessorManager.getNominalRate());
1138     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
1139              m_StreamProcessorManager.getPeriodSize(), m_StreamProcessorManager.getNbBuffers());
1140     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
1141              m_1394service.getPort(), m_channel);
1142
1143     // initialization can be done without requesting it
1144     // from the packet loop
1145     m_next_state = ePS_Stopped;
1146     return updateState();
1147 }
1148
1149 bool
1150 StreamProcessor::scheduleStateTransition(enum eProcessorState state, uint64_t time_instant)
1151 {
1152     // first set the time, since in the packet loop we first check m_state == m_next_state before
1153     // using the time
1154     m_cycle_to_switch_state = TICKS_TO_CYCLES(time_instant);
1155     m_next_state = state;
1156     POST_SEMAPHORE; // needed to ensure that things don't get deadlocked
1157     return true;
1158 }
1159
1160 bool
1161 StreamProcessor::waitForState(enum eProcessorState state, unsigned int timeout_ms)
1162 {
1163     debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting for state %s\n", ePSToString(state));
1164     int cnt = timeout_ms;
1165     while (m_state != state && cnt) {
1166         SleepRelativeUsec(1000);
1167         cnt--;
1168     }
1169     if(cnt==0) {
1170         debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout\n");
1171         return false;
1172     }
1173     return true;
1174 }
1175
1176 bool StreamProcessor::scheduleStartDryRunning(int64_t t) {
1177     uint64_t tx;
1178     if (t < 0) {
1179         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1180     } else {
1181         tx = t;
1182     }
1183     uint64_t start_handler_ticks = substractTicks(tx, 100 * TICKS_PER_CYCLE);
1184
1185     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1186     uint64_t now = m_1394service.getCycleTimerTicks();
1187     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1188                           now,
1189                           (unsigned int)TICKS_TO_SECS(now),
1190                           (unsigned int)TICKS_TO_CYCLES(now),
1191                           (unsigned int)TICKS_TO_OFFSET(now));
1192     debugOutput(DEBUG_LEVEL_VERBOSE,"  Start at              : %011llu (%03us %04uc %04ut)\n",
1193                           tx,
1194                           (unsigned int)TICKS_TO_SECS(tx),
1195                           (unsigned int)TICKS_TO_CYCLES(tx),
1196                           (unsigned int)TICKS_TO_OFFSET(tx));
1197     if (m_state == ePS_Stopped) {
1198         if(!m_IsoHandlerManager.startHandlerForStream(
1199                                         this, TICKS_TO_CYCLES(start_handler_ticks))) {
1200             debugError("Could not start handler for SP %p\n", this);
1201             return false;
1202         }
1203         return scheduleStateTransition(ePS_WaitingForStream, tx);
1204     } else if (m_state == ePS_Running) {
1205         return scheduleStateTransition(ePS_WaitingForStreamDisable, tx);
1206     } else {
1207         debugError("Cannot switch to ePS_DryRunning from %s\n", ePSToString(m_state));
1208         return false;
1209     }
1210 }
1211
1212 bool StreamProcessor::scheduleStartRunning(int64_t t) {
1213     uint64_t tx;
1214     if (t < 0) {
1215         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1216     } else {
1217         tx = t;
1218     }
1219     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1220     uint64_t now = m_1394service.getCycleTimerTicks();
1221     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1222                           now,
1223                           (unsigned int)TICKS_TO_SECS(now),
1224                           (unsigned int)TICKS_TO_CYCLES(now),
1225                           (unsigned int)TICKS_TO_OFFSET(now));
1226     debugOutput(DEBUG_LEVEL_VERBOSE,"  Start at              : %011llu (%03us %04uc %04ut)\n",
1227                           tx,
1228                           (unsigned int)TICKS_TO_SECS(tx),
1229                           (unsigned int)TICKS_TO_CYCLES(tx),
1230                           (unsigned int)TICKS_TO_OFFSET(tx));
1231     return scheduleStateTransition(ePS_WaitingForStreamEnable, tx);
1232 }
1233
1234 bool StreamProcessor::scheduleStopDryRunning(int64_t t) {
1235     uint64_t tx;
1236     if (t < 0) {
1237         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1238     } else {
1239         tx = t;
1240     }
1241     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1242     uint64_t now = m_1394service.getCycleTimerTicks();
1243     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1244                           now,
1245                           (unsigned int)TICKS_TO_SECS(now),
1246                           (unsigned int)TICKS_TO_CYCLES(now),
1247                           (unsigned int)TICKS_TO_OFFSET(now));
1248     debugOutput(DEBUG_LEVEL_VERBOSE,"  Stop at               : %011llu (%03us %04uc %04ut)\n",
1249                           tx,
1250                           (unsigned int)TICKS_TO_SECS(tx),
1251                           (unsigned int)TICKS_TO_CYCLES(tx),
1252                           (unsigned int)TICKS_TO_OFFSET(tx));
1253
1254     return scheduleStateTransition(ePS_Stopped, tx);
1255 }
1256
1257 bool StreamProcessor::scheduleStopRunning(int64_t t) {
1258     uint64_t tx;
1259     if (t < 0) {
1260         tx = addTicks(m_1394service.getCycleTimerTicks(), 200 * TICKS_PER_CYCLE);
1261     } else {
1262         tx = t;
1263     }
1264     debugOutput(DEBUG_LEVEL_VERBOSE,"for %s SP (%p)\n", ePTToString(getType()), this);
1265     uint64_t now = m_1394service.getCycleTimerTicks();
1266     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011llu (%03us %04uc %04ut)\n",
1267                           now,
1268                           (unsigned int)TICKS_TO_SECS(now),
1269                           (unsigned int)TICKS_TO_CYCLES(now),
1270                           (unsigned int)TICKS_TO_OFFSET(now));
1271     debugOutput(DEBUG_LEVEL_VERBOSE,"  Stop at               : %011llu (%03us %04uc %04ut)\n",
1272                           tx,
1273                           (unsigned int)TICKS_TO_SECS(tx),
1274                           (unsigned int)TICKS_TO_CYCLES(tx),
1275                           (unsigned int)TICKS_TO_OFFSET(tx));
1276     return scheduleStateTransition(ePS_WaitingForStreamDisable, tx);
1277 }
1278
1279 bool StreamProcessor::startDryRunning(int64_t t) {
1280     if(!scheduleStartDryRunning(t)) {
1281         debugError("Could not schedule transition\n");
1282         return false;
1283     }
1284     if(!waitForState(ePS_DryRunning, 2000)) {
1285         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_DryRunning));
1286         return false;
1287     }
1288     return true;
1289 }
1290
1291 bool StreamProcessor::startRunning(int64_t t) {
1292     if(!scheduleStartRunning(t)) {
1293         debugError("Could not schedule transition\n");
1294         return false;
1295     }
1296     if(!waitForState(ePS_Running, 2000)) {
1297         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_Running));
1298         return false;
1299     }
1300     return true;
1301 }
1302
1303 bool StreamProcessor::stopDryRunning(int64_t t) {
1304     if(!scheduleStopDryRunning(t)) {
1305         debugError("Could not schedule transition\n");
1306         return false;
1307     }
1308     if(!waitForState(ePS_Stopped, 2000)) {
1309         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_Stopped));
1310         return false;
1311     }
1312     return true;
1313 }
1314
1315 bool StreamProcessor::stopRunning(int64_t t) {
1316     if(!scheduleStopRunning(t)) {
1317         debugError("Could not schedule transition\n");
1318         return false;
1319     }
1320     if(!waitForState(ePS_DryRunning, 2000)) {
1321         debugError(" Timeout while waiting for %s\n", ePSToString(ePS_DryRunning));
1322         return false;
1323     }
1324     return true;
1325 }
1326
1327
1328 // internal state API
1329
1330 /**
1331  * @brief Enter the ePS_Stopped state
1332  * @return true if successful, false if not
1333  *
1334  * @pre none
1335  *
1336  * @post the buffer and the isostream are ready for use.
1337  * @post all dynamic structures have been allocated successfully
1338  * @post the buffer is transparent and empty, and all parameters are set
1339  *       to the correct initial/nominal values.
1340  *
1341  */
1342 bool
1343 StreamProcessor::doStop()
1344 {
1345     float ticks_per_frame;
1346     unsigned int ringbuffer_size_frames = (m_StreamProcessorManager.getNbBuffers() + 1) * m_StreamProcessorManager.getPeriodSize();
1347
1348     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1349     bool result = true;
1350
1351     switch(m_state) {
1352         case ePS_Created:
1353             assert(m_data_buffer);
1354
1355             // prepare the framerate estimate
1356             ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_StreamProcessorManager.getNominalRate());
1357             m_ticks_per_frame = ticks_per_frame;
1358             m_local_node_id= m_1394service.getLocalNodeId() & 0x3f;
1359             m_correct_last_timestamp = false;
1360
1361             debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame);
1362
1363             // initialize internal buffer
1364             result &= m_data_buffer->setBufferSize(ringbuffer_size_frames);
1365
1366             result &= m_data_buffer->setEventSize( getEventSize() );
1367             result &= m_data_buffer->setEventsPerFrame( getEventsPerFrame() );
1368             if(getType() == ePT_Receive) {
1369                 result &= m_data_buffer->setUpdatePeriod( getNominalFramesPerPacket() );
1370             } else {
1371                 result &= m_data_buffer->setUpdatePeriod( m_StreamProcessorManager.getPeriodSize() );
1372             }
1373             result &= m_data_buffer->setNominalRate(ticks_per_frame);
1374             result &= m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
1375             result &= m_data_buffer->prepare(); // FIXME: the name
1376
1377             break;
1378         case ePS_DryRunning:
1379             if(!m_IsoHandlerManager.stopHandlerForStream(this)) {
1380                 debugError("Could not stop handler for SP %p\n", this);
1381                 return false;
1382             }
1383             break;
1384         default:
1385             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1386             return false;
1387     }
1388
1389     result &= m_data_buffer->clearBuffer(); // FIXME: don't like the reset() name
1390     // make the buffer transparent
1391     m_data_buffer->setTransparent(true);
1392
1393     // reset all ports
1394     result &= PortManager::preparePorts();
1395
1396     m_state = ePS_Stopped;
1397     #ifdef DEBUG
1398     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1399         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1400         dumpInfo();
1401     }
1402     #endif
1403     return result;
1404 }
1405
1406 /**
1407  * @brief Enter the ePS_WaitingForStream state
1408  * @return true if successful, false if not
1409  *
1410  * @pre all dynamic data structures are allocated successfully
1411  *
1412  * @post
1413  *
1414  */
1415 bool
1416 StreamProcessor::doWaitForRunningStream()
1417 {
1418     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1419     switch(m_state) {
1420         case ePS_Stopped:
1421             // we have to start waiting for an incoming stream
1422             // this basically means nothing, the state change will
1423             // be picked up by the packet iterator
1424             break;
1425         default:
1426             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1427             return false;
1428     }
1429     m_state = ePS_WaitingForStream;
1430     #ifdef DEBUG
1431     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1432         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1433         dumpInfo();
1434     }
1435     #endif
1436     return true;
1437 }
1438
1439 /**
1440  * @brief Enter the ePS_DryRunning state
1441  * @return true if successful, false if not
1442  *
1443  * @pre
1444  *
1445  * @post
1446  *
1447  */
1448 bool
1449 StreamProcessor::doDryRunning()
1450 {
1451     bool result = true;
1452     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1453     switch(m_state) {
1454         case ePS_WaitingForStream:
1455             // a running stream has been detected
1456             debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started dry-running at cycle %d\n", this, m_last_cycle);
1457             m_local_node_id = m_1394service.getLocalNodeId() & 0x3f;
1458             if (getType() == ePT_Receive) {
1459                 // this to ensure that there is no discontinuity when starting to
1460                 // update the DLL based upon the received packets
1461                 m_data_buffer->setBufferTailTimestamp(m_last_timestamp);
1462             } else {
1463                 // FIXME: PC=master mode will have to do something here I guess...
1464             }
1465             break;
1466         case ePS_WaitingForStreamEnable: // when xrunning at startup
1467             result &= m_data_buffer->clearBuffer();
1468             m_data_buffer->setTransparent(true);
1469             break;
1470         case ePS_WaitingForStreamDisable:
1471             result &= m_data_buffer->clearBuffer();
1472             m_data_buffer->setTransparent(true);
1473             break;
1474         default:
1475             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1476             return false;
1477     }
1478     m_state = ePS_DryRunning;
1479     #ifdef DEBUG
1480     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1481         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1482         dumpInfo();
1483     }
1484     #endif
1485     return result;
1486 }
1487
1488 /**
1489  * @brief Enter the ePS_WaitingForStreamEnable state
1490  * @return true if successful, false if not
1491  *
1492  * @pre
1493  *
1494  * @post
1495  *
1496  */
1497 bool
1498 StreamProcessor::doWaitForStreamEnable()
1499 {
1500     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1501     unsigned int ringbuffer_size_frames;
1502     switch(m_state) {
1503         case ePS_DryRunning:
1504             // we have to start waiting for an incoming stream
1505             // this basically means nothing, the state change will
1506             // be picked up by the packet iterator
1507
1508             sem_init(&m_signal_semaphore, 0, 0);
1509             m_signal_period = m_StreamProcessorManager.getPeriodSize();
1510             m_signal_offset = 0; // FIXME: we have to ensure that everyone is ready
1511
1512             if(!m_data_buffer->clearBuffer()) {
1513                 debugError("Could not reset data buffer\n");
1514                 return false;
1515             }
1516             if (getType() == ePT_Transmit) {
1517                 ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize();
1518                 debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames\n", this, ringbuffer_size_frames);
1519                 // prefill the buffer
1520                 if(!transferSilence(ringbuffer_size_frames)) {
1521                     debugFatal("Could not prefill transmit stream\n");
1522                     return false;
1523                 }
1524                 if (m_data_buffer->getBufferFill() >= m_signal_period + m_signal_offset) {
1525                     POST_SEMAPHORE;
1526                 }
1527             }
1528
1529             break;
1530         default:
1531             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1532             return false;
1533     }
1534     m_state = ePS_WaitingForStreamEnable;
1535     #ifdef DEBUG
1536     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1537         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1538         dumpInfo();
1539     }
1540     #endif
1541     return true;
1542 }
1543
1544 /**
1545  * @brief Enter the ePS_Running state
1546  * @return true if successful, false if not
1547  *
1548  * @pre
1549  *
1550  * @post
1551  *
1552  */
1553 bool
1554 StreamProcessor::doRunning()
1555 {
1556     bool result = true;
1557     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1558     switch(m_state) {
1559         case ePS_WaitingForStreamEnable:
1560             // a running stream has been detected
1561             debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started running at cycle %d\n",
1562                                              this, m_last_cycle);
1563             m_in_xrun = false;
1564             m_local_node_id = m_1394service.getLocalNodeId() & 0x3f;
1565             m_data_buffer->setTransparent(false);
1566             break;
1567         default:
1568             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1569             return false;
1570     }
1571     m_state = ePS_Running;
1572     #ifdef DEBUG
1573     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1574         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1575         dumpInfo();
1576     }
1577     #endif
1578     return result;
1579 }
1580
1581 /**
1582  * @brief Enter the ePS_WaitingForStreamDisable state
1583  * @return true if successful, false if not
1584  *
1585  * @pre
1586  *
1587  * @post
1588  *
1589  */
1590 bool
1591 StreamProcessor::doWaitForStreamDisable()
1592 {
1593     debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state));
1594     switch(m_state) {
1595         case ePS_Running:
1596             // the thread will do the transition
1597
1598             // we have to wake the iterator if it's asleep
1599             POST_SEMAPHORE;
1600             break;
1601         default:
1602             debugError("Entry from invalid state: %s\n", ePSToString(m_state));
1603             return false;
1604     }
1605     m_state = ePS_WaitingForStreamDisable;
1606     #ifdef DEBUG
1607     if (getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
1608         debugOutput(DEBUG_LEVEL_VERBOSE, "State switch complete, dumping SP info...\n");
1609         dumpInfo();
1610     }
1611     #endif
1612     return true;
1613 }
1614
1615 /**
1616  * @brief Updates the state machine and calls the necessary transition functions
1617  * @return true if successful, false if not
1618  */
1619 bool StreamProcessor::updateState() {
1620     bool result = false;
1621     // copy the current state locally since it could change value,
1622     // and that's something we don't want to happen inbetween tests
1623     // if m_next_state changes during this routine, we know for sure
1624     // that the previous state change was at least attempted correctly.
1625     enum eProcessorState next_state = m_next_state;
1626
1627     debugOutput(DEBUG_LEVEL_VERBOSE, "Do state transition: %s => %s\n",
1628         ePSToString(m_state), ePSToString(next_state));
1629
1630     if (m_state == next_state) {
1631         debugWarning("ignoring identity state update from/to %s\n", ePSToString(m_state) );
1632         return true;
1633     }
1634
1635     // after creation, only initialization is allowed
1636     if (m_state == ePS_Created) {
1637         if(next_state != ePS_Stopped) {
1638             goto updateState_exit_with_error;
1639         }
1640         // do init here
1641         result = doStop();
1642         if (result) {POST_SEMAPHORE; return true;}
1643         else goto updateState_exit_change_failed;
1644     }
1645
1646     // after initialization, only WaitingForRunningStream is allowed
1647     if (m_state == ePS_Stopped) {
1648         if(next_state != ePS_WaitingForStream) {
1649             goto updateState_exit_with_error;
1650         }
1651         result = doWaitForRunningStream();
1652         if (result) {POST_SEMAPHORE; return true;}
1653         else goto updateState_exit_change_failed;
1654     }
1655
1656     // after WaitingForStream, only ePS_DryRunning is allowed
1657     // this means that the stream started running
1658     if (m_state == ePS_WaitingForStream) {
1659         if(next_state != ePS_DryRunning) {
1660             goto updateState_exit_with_error;
1661         }
1662         result = doDryRunning();
1663         if (result) {POST_SEMAPHORE; return true;}
1664         else goto updateState_exit_change_failed;
1665     }
1666
1667     // from ePS_DryRunning we can go to:
1668     //   - ePS_Stopped if something went wrong during DryRunning
1669     //   - ePS_WaitingForStreamEnable if there is a requested to enable
1670     if (m_state == ePS_DryRunning) {
1671         if((next_state != ePS_Stopped) &&
1672            (next_state != ePS_WaitingForStreamEnable)) {
1673             goto updateState_exit_with_error;
1674         }
1675         if (next_state == ePS_Stopped) {
1676             result = doStop();
1677         } else {
1678             result = doWaitForStreamEnable();
1679         }
1680         if (result) {POST_SEMAPHORE; return true;}
1681         else goto updateState_exit_change_failed;
1682     }
1683
1684     // from ePS_WaitingForStreamEnable we can go to:
1685     //   - ePS_DryRunning if something went wrong while waiting
1686     //   - ePS_Running if the stream enabled correctly
1687     if (m_state == ePS_WaitingForStreamEnable) {
1688         if((next_state != ePS_DryRunning) &&
1689            (next_state != ePS_Running)) {
1690             goto updateState_exit_with_error;
1691         }
1692         if (next_state == ePS_Stopped) {
1693             result = doDryRunning();
1694         } else {
1695             result = doRunning();
1696         }
1697         if (result) {POST_SEMAPHORE; return true;}
1698         else goto updateState_exit_change_failed;
1699     }
1700
1701     // from ePS_Running we can only start waiting for a disabled stream
1702     if (m_state == ePS_Running) {
1703         if(next_state != ePS_WaitingForStreamDisable) {
1704             goto updateState_exit_with_error;
1705         }
1706         result = doWaitForStreamDisable();
1707         if (result) {POST_SEMAPHORE; return true;}
1708         else goto updateState_exit_change_failed;
1709     }
1710
1711     // from ePS_WaitingForStreamDisable we can go to DryRunning
1712     if (m_state == ePS_WaitingForStreamDisable) {
1713         if(next_state != ePS_DryRunning) {
1714             goto updateState_exit_with_error;
1715         }
1716         result = doDryRunning();
1717         if (result) {POST_SEMAPHORE; return true;}
1718         else goto updateState_exit_change_failed;
1719     }
1720
1721     // if we arrive here there is an error
1722 updateState_exit_with_error:
1723     debugError("Invalid state transition: %s => %s\n",
1724         ePSToString(m_state), ePSToString(next_state));
1725     POST_SEMAPHORE;
1726     return false;
1727 updateState_exit_change_failed:
1728     debugError("State transition failed: %s => %s\n",
1729         ePSToString(m_state), ePSToString(next_state));
1730     POST_SEMAPHORE;
1731     return false;
1732 }
1733
1734 /***********************************************
1735  * Helper routines                             *
1736  ***********************************************/
1737 bool
1738 StreamProcessor::transferSilence(unsigned int nframes)
1739 {
1740     bool retval;
1741     signed int fc;
1742     ffado_timestamp_t ts_tail_tmp;
1743
1744     // prepare a buffer of silence
1745     char *dummybuffer = (char *)calloc(getEventSize(), nframes * getEventsPerFrame());
1746     transmitSilenceBlock(dummybuffer, nframes, 0);
1747
1748     m_data_buffer->getBufferTailTimestamp(&ts_tail_tmp, &fc);
1749     if (fc != 0) {
1750         debugWarning("Prefilling a buffer that already contains %d frames\n", fc);
1751     }
1752
1753     // add the silence data to the ringbuffer
1754     if(m_data_buffer->preloadFrames(nframes, dummybuffer, true)) {
1755         retval = true;
1756     } else {
1757         debugWarning("Could not write to event buffer\n");
1758         retval = false;
1759     }
1760     free(dummybuffer);
1761     return retval;
1762 }
1763
1764 /**
1765  * @brief convert a eProcessorState to a string
1766  * @param s the state
1767  * @return a char * describing the state
1768  */
1769 const char *
1770 StreamProcessor::ePSToString(enum eProcessorState s) {
1771     switch (s) {
1772         case ePS_Invalid: return "ePS_Invalid";
1773         case ePS_Created: return "ePS_Created";
1774         case ePS_Stopped: return "ePS_Stopped";
1775         case ePS_WaitingForStream: return "ePS_WaitingForStream";
1776         case ePS_DryRunning: return "ePS_DryRunning";
1777         case ePS_WaitingForStreamEnable: return "ePS_WaitingForStreamEnable";
1778         case ePS_Running: return "ePS_Running";
1779         case ePS_WaitingForStreamDisable: return "ePS_WaitingForStreamDisable";
1780         default: return "error: unknown state";
1781     }
1782 }
1783
1784 /**
1785  * @brief convert a eProcessorType to a string
1786  * @param t the type
1787  * @return a char * describing the state
1788  */
1789 const char *
1790 StreamProcessor::ePTToString(enum eProcessorType t) {
1791     switch (t) {
1792         case ePT_Receive: return "Receive";
1793         case ePT_Transmit: return "Transmit";
1794         default: return "error: unknown type";
1795     }
1796 }
1797
1798 /***********************************************
1799  * Debug                                       *
1800  ***********************************************/
1801 void
1802 StreamProcessor::dumpInfo()
1803 {
1804     debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor %p, %s:\n", this, ePTToString(m_processor_type));
1805     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel  : %d, %d\n", m_1394service.getPort(), m_channel);
1806     uint64_t now = m_1394service.getCycleTimerTicks();
1807     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011llu (%03us %04uc %04ut)\n",
1808                         now,
1809                         (unsigned int)TICKS_TO_SECS(now),
1810                         (unsigned int)TICKS_TO_CYCLES(now),
1811                         (unsigned int)TICKS_TO_OFFSET(now));
1812     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xrun?                 : %s\n", (m_in_xrun ? "True":"False"));
1813     if (m_state == m_next_state) {
1814         debugOutputShort( DEBUG_LEVEL_NORMAL, "  State                 : %s\n",
1815                                             ePSToString(m_state));
1816     } else {
1817         debugOutputShort( DEBUG_LEVEL_NORMAL, "  State                 : %s (Next: %s)\n",
1818                                               ePSToString(m_state), ePSToString(m_next_state));
1819         debugOutputShort( DEBUG_LEVEL_NORMAL, "    transition at       : %u\n", m_cycle_to_switch_state);
1820     }
1821     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer                : %p\n", m_data_buffer);
1822     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Framerate             : Nominal: %u, Sync: %f, Buffer %f\n",
1823                                           m_StreamProcessorManager.getNominalRate(),
1824                                           24576000.0/m_StreamProcessorManager.getSyncSource().m_data_buffer->getRate(),
1825                                           24576000.0/m_data_buffer->getRate());
1826     float d = getSyncDelay();
1827     debugOutputShort(DEBUG_LEVEL_NORMAL, "  Sync delay             : %f ticks (%f frames, %f cy)\n",
1828                                          d, d/getTicksPerFrame(),
1829                                          d/((float)TICKS_PER_CYCLE));
1830     m_data_buffer->dumpInfo();
1831 }
1832
1833 void
1834 StreamProcessor::setVerboseLevel(int l) {
1835     setDebugLevel(l);
1836     PortManager::setVerboseLevel(l);
1837     m_data_buffer->setVerboseLevel(l);
1838 }
1839
1840 } // end of namespace
Note: See TracBrowser for help on using the browser.