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

Revision 766, 60.1 kB (checked in by ppalmers, 13 years ago)

introduce local references to frequently used objects

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