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

Revision 775, 60.7 kB (checked in by ppalmers, 13 years ago)

- sleep before AGAIN, fixed deadlock

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