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

Revision 750, 59.8 kB (checked in by ppalmers, 13 years ago)

Code refactoring. Tries to simplify things and tries to put all code where it belongs.

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