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

Revision 759, 60.4 kB (checked in by ppalmers, 13 years ago)

fix streaming problem

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