root/trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

Revision 2802, 70.7 kB (checked in by jwoithe, 3 years ago)

Cosmetic: "Firewire" becomes "FireWire?".

Officially both the "F" and "W" were capitalised in the FireWire? name, so
reflect this throughout FFADO's source tree. This mostly affects comments.

This patch originated from pander on the ffado-devel mailing list. To
maintain consistency, the committed version has been expanded to include
files not originally included in the original patch.

Line 
1 /*
2  * Copyright (C) 2005-2008 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 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25
26 #include "StreamProcessorManager.h"
27 #include "generic/StreamProcessor.h"
28 #include "generic/Port.h"
29 #include "libieee1394/cycletimer.h"
30
31 #include "devicemanager.h"
32
33 #include "libutil/Time.h"
34
35 #include <errno.h>
36 #include <assert.h>
37 #include <math.h>
38
39 namespace Streaming {
40
41 IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE );
42
43 StreamProcessorManager::StreamProcessorManager(DeviceManager &p)
44     : m_time_of_transfer ( 0 )
45     #ifdef DEBUG
46     , m_time_of_transfer2 ( 0 )
47     #endif
48     , m_is_slave( false )
49     , m_SyncSource(NULL)
50     , m_parent( p )
51     , m_xrun_happened( false )
52     , m_activity_wait_timeout_nsec( 0 ) // dynamically set
53     , m_nb_buffers( 0 )
54     , m_period( 0 )
55     , m_sync_delay( 0 )
56     , m_audio_datatype( eADT_Float )
57     , m_nominal_framerate ( 0 )
58     , m_xruns(0)
59     , m_shutdown_needed(false)
60     , m_nbperiods(0)
61     , m_WaitLock( new Util::PosixMutex("SPMWAIT") )
62     , m_max_diff_ticks( 50 )
63 {
64     addOption(Util::OptionContainer::Option("slaveMode",false));
65     sem_init(&m_activity_semaphore, 0, 0);
66 }
67
68 StreamProcessorManager::StreamProcessorManager(DeviceManager &p, unsigned int period,
69                                                unsigned int framerate, unsigned int nb_buffers)
70     : m_time_of_transfer ( 0 )
71     #ifdef DEBUG
72     , m_time_of_transfer2 ( 0 )
73     #endif
74     , m_is_slave( false )
75     , m_SyncSource(NULL)
76     , m_parent( p )
77     , m_xrun_happened( false )
78     , m_activity_wait_timeout_nsec( 0 ) // dynamically set
79     , m_nb_buffers(nb_buffers)
80     , m_period(period)
81     , m_sync_delay( 0 )
82     , m_audio_datatype( eADT_Float )
83     , m_nominal_framerate ( framerate )
84     , m_xruns(0)
85     , m_shutdown_needed(false)
86     , m_nbperiods(0)
87     , m_WaitLock( new Util::PosixMutex("SPMWAIT") )
88     , m_max_diff_ticks( 50 )
89 {
90     addOption(Util::OptionContainer::Option("slaveMode",false));
91     sem_init(&m_activity_semaphore, 0, 0);
92 }
93
94 StreamProcessorManager::~StreamProcessorManager() {
95     sem_post(&m_activity_semaphore);
96     sem_destroy(&m_activity_semaphore);
97     delete m_WaitLock;
98 }
99
100 // void
101 // StreamProcessorManager::handleBusReset(Ieee1394Service &s)
102 // {
103 // //     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset on service %p...\n", this, &s);
104 // //
105 // //     bool handled_at_least_one = false;
106 // //     // note that all receive streams are gone once a device is unplugged
107 // //
108 // //     // synchronize with the wait lock
109 // //     Util::MutexLockHelper lock(*m_WaitLock);
110 // //
111 // //     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this);
112 // //     // cause all SP's to bail out
113 // //     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
114 // //           it != m_ReceiveProcessors.end();
115 // //           ++it )
116 // //     {
117 // //         if(&s == &((*it)->getParent().get1394Service())) {
118 // //             debugOutput(DEBUG_LEVEL_NORMAL,
119 // //                         "issue busreset on receive SPM on channel %d\n",
120 // //                         (*it)->getChannel());
121 // //             (*it)->handleBusReset();
122 // //             handled_at_least_one = true;
123 // //         } else {
124 // //             debugOutput(DEBUG_LEVEL_NORMAL,
125 // //                         "skipping receive SPM on channel %d since not on service %p\n",
126 // //                         (*it)->getChannel(), &s);
127 // //         }
128 // //     }
129 // //     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
130 // //           it != m_TransmitProcessors.end();
131 // //           ++it )
132 // //     {
133 // //         if(&s == &((*it)->getParent().get1394Service())) {
134 // //             debugOutput(DEBUG_LEVEL_NORMAL,
135 // //                         "issue busreset on transmit SPM on channel %d\n",
136 // //                         (*it)->getChannel());
137 // //             (*it)->handleBusReset();
138 // //             handled_at_least_one = true;
139 // //         } else {
140 // //             debugOutput(DEBUG_LEVEL_NORMAL,
141 // //                         "skipping transmit SPM on channel %d since not on service %p\n",
142 // //                         (*it)->getChannel(), &s);
143 // //         }
144 // //     }
145 // //
146 // //     // FIXME: we request shutdown for now.
147 // //     m_shutdown_needed = handled_at_least_one;
148 // }
149
150 void
151 StreamProcessorManager::signalActivity()
152 {
153     sem_post(&m_activity_semaphore);
154     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,"%p activity\n", this);
155 }
156
157 enum StreamProcessorManager::eActivityResult
158 StreamProcessorManager::waitForActivity()
159 {
160     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,"%p waiting for activity\n", this);
161     struct timespec ts;
162     int result;
163
164     if (m_activity_wait_timeout_nsec >= 0) {
165
166         // CLOCK_REALTIME must be used because that's what sem_timedwait()
167         // uses.  This is safe - regardless of the clock used by
168         // Util::SystemTimeSource - so long as the resulting time is only
169         // used to implement a timeout in sem_timedwait().
170         if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
171             debugError("clock_gettime failed\n");
172             return eAR_Error;
173         }
174         ts.tv_nsec += m_activity_wait_timeout_nsec;
175         while(ts.tv_nsec >= 1000000000LL) {
176             ts.tv_sec += 1;
177             ts.tv_nsec -= 1000000000LL;
178         }
179     }
180
181     if (m_activity_wait_timeout_nsec >= 0) {
182         result = sem_timedwait(&m_activity_semaphore, &ts);
183     } else {
184         result = sem_wait(&m_activity_semaphore);
185     }
186
187     if(result != 0) {
188         if (errno == ETIMEDOUT) {
189             debugOutput(DEBUG_LEVEL_VERBOSE,
190                         "(%p) sem_timedwait() timed out (result=%d)\n",
191                         this, result);
192             return eAR_Timeout;
193         } else if (errno == EINTR) {
194             debugOutput(DEBUG_LEVEL_VERBOSE,
195                         "(%p) sem_[timed]wait() interrupted by signal (result=%d)\n",
196                         this, result);
197             return eAR_Interrupted;
198         } else if (errno == EINVAL) {
199             debugError("(%p) sem_[timed]wait error (result=%d errno=EINVAL)\n",
200                         this, result);
201             debugError("(%p) timeout_nsec=%" PRId64 " ts.sec=%" PRId64 " ts.nsec=%" PRId64 "\n",
202                        this, m_activity_wait_timeout_nsec,
203                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
204             return eAR_Error;
205         } else {
206             debugError("(%p) sem_[timed]wait error (result=%d errno=%d)\n",
207                         this, result, errno);
208             debugError("(%p) timeout_nsec=%" PRId64 " ts.sec=%" PRId64 " ts.nsec=%" PRId64 "\n",
209                        this, m_activity_wait_timeout_nsec,
210                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
211             return eAR_Error;
212         }
213     }
214
215     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,"%p got activity\n", this);
216     return eAR_Activity;
217 }
218
219 /**
220  * Registers \ref processor with this manager.
221  *
222  * also registers it with the isohandlermanager
223  *
224  * be sure to call isohandlermanager->init() first!
225  * and be sure that the processors are also ->init()'ed
226  *
227  * @param processor
228  * @return true if successfull
229  */
230 bool StreamProcessorManager::registerProcessor(StreamProcessor *processor)
231 {
232     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering processor (%p)\n",processor);
233     assert(processor);
234     if (processor->getType() == StreamProcessor::ePT_Receive) {
235         processor->setVerboseLevel(getDebugLevel()); // inherit debug level
236         m_ReceiveProcessors.push_back(processor);
237         Util::Functor* f = new Util::MemberFunctor0< StreamProcessorManager*, void (StreamProcessorManager::*)() >
238                     ( this, &StreamProcessorManager::updateShadowLists, false );
239         processor->addPortManagerUpdateHandler(f);
240         updateShadowLists();
241         return true;
242     }
243     if (processor->getType() == StreamProcessor::ePT_Transmit) {
244         processor->setVerboseLevel(getDebugLevel()); // inherit debug level
245         m_TransmitProcessors.push_back(processor);
246         Util::Functor* f = new Util::MemberFunctor0< StreamProcessorManager*, void (StreamProcessorManager::*)() >
247                     ( this, &StreamProcessorManager::updateShadowLists, false );
248         processor->addPortManagerUpdateHandler(f);
249         updateShadowLists();
250         return true;
251     }
252
253     debugFatal("Unsupported processor type!\n");
254     return false;
255 }
256
257 bool StreamProcessorManager::unregisterProcessor(StreamProcessor *processor)
258 {
259     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering processor (%p)\n",processor);
260     assert(processor);
261
262     if (processor->getType()==StreamProcessor::ePT_Receive) {
263
264         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
265               it != m_ReceiveProcessors.end();
266               ++it )
267         {
268             if ( *it == processor ) {
269                 if (*it == m_SyncSource) {
270                     debugOutput(DEBUG_LEVEL_VERBOSE, "unregistering sync source\n");
271                     m_SyncSource = NULL;
272                 }
273                 m_ReceiveProcessors.erase(it);
274                 // remove the functor
275                 Util::Functor * f = processor->getUpdateHandlerForPtr(this);
276                 if(f) {
277                     processor->remPortManagerUpdateHandler(f);
278                     delete f;
279                 }
280                 updateShadowLists();
281                 return true;
282             }
283         }
284     }
285
286     if (processor->getType()==StreamProcessor::ePT_Transmit) {
287         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
288               it != m_TransmitProcessors.end();
289               ++it )
290         {
291             if ( *it == processor ) {
292                 if (*it == m_SyncSource) {
293                     debugOutput(DEBUG_LEVEL_VERBOSE, "unregistering sync source\n");
294                     m_SyncSource = NULL;
295                 }
296                 m_TransmitProcessors.erase(it);
297                 // remove the functor
298                 Util::Functor * f = processor->getUpdateHandlerForPtr(this);
299                 if(f) {
300                     processor->remPortManagerUpdateHandler(f);
301                     delete f;
302                 }
303                 updateShadowLists();
304                 return true;
305             }
306         }
307     }
308
309     debugFatal("Processor (%p) not found!\n",processor);
310     return false; //not found
311 }
312
313 bool StreamProcessorManager::streamingParamsOk(signed int period, signed int rate, signed int n_buffers)
314 {
315     // Return true if the given parameter combination is valid.  If any
316     // parameter is set to -1 the currently set value is used in the test.
317     signed int min_period;
318
319     if (period < 0)
320         period = m_period;
321     if (rate < 0)
322         rate = m_nominal_framerate;
323     if (n_buffers < 0)
324         n_buffers = m_nb_buffers;
325
326     // For most interfaces data is transmitted with 8/16/32 samples per
327     // packet (at 1x, 2x and 4x rates respectively).  This more or less
328     // places a lower limit on the size of the period.  Furthermore, the
329     // current FFADO architecture dictates that m_nb_buffers can be no lower
330     // than 2.
331
332     if (n_buffers < 2) {
333         printMessage("FFADO requires at least 2 buffers\n");
334         return false;
335     }
336
337     // The boundary between 1x, 2x and 4x speed is taken from the RME driver
338     // since this seems to be the device with the widest available sampling
339     // rate range.
340     if (rate < 56000) {
341         // 1x speed
342         min_period = 8;
343     } else
344     if (rate < 112000) {
345         // 2x speed
346         min_period = 16;
347     } else {
348         // 4x speed
349         min_period = 32;
350     }
351
352     if (period < min_period) {
353         printMessage("At a rate of %d Hz, FFADO requires a buffer size of at least %d samples\n",
354             rate, min_period);
355         return false;
356     }
357     return true;
358 }
359
360 void StreamProcessorManager::setPeriodSize(unsigned int period) {
361     // This method is called early in the initialisation sequence to set the
362     // initial period size.  However, at that point in time the stream
363     // processors haven't been registered so they won't have their buffers
364     // configured from here.  The initial allocation of the stream processor
365     // (SP) buffers happens from within the SP prepare() method.
366     //
367     // SP period size changes will normally only be acted on from here
368     // if the change comes about due to a runtime change in the buffer size,
369     // as happens via jack's setbufsize facility for example.
370
371     if (period == m_period)
372         return;
373
374     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting period size to %d (was %d)\n", period, m_period);
375     m_period = period;
376
377     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
378           it != m_ReceiveProcessors.end();
379           ++it )
380     {
381         if ((*it)->periodSizeChanged(period) == false)
382             debugWarning("receive stream processor %p couldn't set period size\n", *it);
383     }
384     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
385           it != m_TransmitProcessors.end();
386           ++it )
387     {
388         if ((*it)->periodSizeChanged(period) == false)
389             debugWarning("transmit stream processor %p couldn't set period size\n", *it);
390     }
391
392     // Keep the activity timeout in sync with the new period size.  See
393     // also comments about this in prepare().
394     if (m_nominal_framerate > 0) {
395         int timeout_usec = 2*1000LL * 1000LL * m_period / m_nominal_framerate;
396         debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec);
397         setActivityWaitTimeoutUsec(timeout_usec);
398     }
399 }
400
401 bool StreamProcessorManager::setSyncSource(StreamProcessor *s) {
402     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting sync source to (%p)\n", s);
403     m_SyncSource = s;
404     return true;
405 }
406
407 bool StreamProcessorManager::prepare() {
408
409     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
410     m_is_slave=false;
411     if(!getOption("slaveMode", m_is_slave)) {
412         debugWarning("Could not retrieve slaveMode parameter, defaulting to false\n");
413     }
414
415     m_shutdown_needed=false;
416
417     // if no sync source is set, select one here
418     if(m_SyncSource == NULL) {
419        debugWarning("Sync Source is not set. Defaulting to first StreamProcessor.\n");
420     }
421
422     // FIXME: put into separate method
423     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
424           it != m_ReceiveProcessors.end();
425           ++it )
426     {
427         if(m_SyncSource == NULL) {
428             debugWarning(" => Sync Source is %p.\n", *it);
429             m_SyncSource = *it;
430         }
431     }
432     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
433           it != m_TransmitProcessors.end();
434           ++it )
435     {
436         if(m_SyncSource == NULL) {
437             debugWarning(" => Sync Source is %p.\n", *it);
438             m_SyncSource = *it;
439         }
440     }
441
442     // now do the actual preparation of the SP's
443     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Receive processors...\n");
444     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
445         it != m_ReceiveProcessors.end();
446         ++it ) {
447
448         if(!(*it)->setOption("slaveMode", m_is_slave)) {
449             debugOutput(DEBUG_LEVEL_VERBOSE, " note: could not set slaveMode option for (%p)...\n",(*it));
450         }
451
452         if(!(*it)->prepare()) {
453             debugFatal(  " could not prepare (%p)...\n",(*it));
454             return false;
455         }
456     }
457     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Transmit processors...\n");
458     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
459         it != m_TransmitProcessors.end();
460         ++it ) {
461         if(!(*it)->setOption("slaveMode", m_is_slave)) {
462             debugOutput(DEBUG_LEVEL_VERBOSE, " note: could not set slaveMode option for (%p)...\n",(*it));
463         }
464         if(!(*it)->prepare()) {
465             debugFatal( " could not prepare (%p)...\n",(*it));
466             return false;
467         }
468     }
469
470     // if there are no stream processors registered,
471     // fail
472     if (m_ReceiveProcessors.size() + m_TransmitProcessors.size() == 0) {
473         debugFatal("No stream processors registered, can't do anything useful\n");
474         return false;
475     }
476
477     // set the activity timeout value to two periods worth of usecs.
478     // since we can expect activity once every period, but we might have some
479     // offset, the safe value is two periods.
480     int timeout_usec = 2*1000LL * 1000LL * m_period / m_nominal_framerate;
481     debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec);
482     setActivityWaitTimeoutUsec(timeout_usec);
483
484     updateShadowLists();
485
486     return true;
487 }
488
489 bool
490 StreamProcessorManager::startDryRunning()
491 {
492     debugOutput( DEBUG_LEVEL_VERBOSE, "Putting StreamProcessor streams into dry-running state...\n");
493     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
494             it != m_TransmitProcessors.end();
495             ++it ) {
496         if ((*it)->inError()) {
497             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it);
498             return false;
499         }
500         if (!(*it)->isDryRunning()) {
501             if(!(*it)->scheduleStartDryRunning(-1)) {
502                 debugError("Could not put '%s' SP %p into the dry-running state\n", (*it)->getTypeString(), *it);
503                 return false;
504             }
505         } else {
506             debugOutput( DEBUG_LEVEL_VERBOSE, " SP %p already dry-running...\n", *it);
507         }
508     }
509     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
510             it != m_ReceiveProcessors.end();
511             ++it ) {
512         if ((*it)->inError()) {
513             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it);
514             return false;
515         }
516         if (!(*it)->isDryRunning()) {
517             if(!(*it)->scheduleStartDryRunning(-1)) {
518                 debugError("Could not put '%s' SP %p into the dry-running state\n", (*it)->getTypeString(), *it);
519                 return false;
520             }
521         } else {
522             debugOutput( DEBUG_LEVEL_VERBOSE, " SP %p already dry-running...\n", *it);
523         }
524     }
525     debugOutput( DEBUG_LEVEL_VERBOSE, " Waiting for all SP's to be dry-running...\n");
526     // wait for the syncsource to start running.
527     // that will block the waitForPeriod call until everyone has started (theoretically)
528     int cnt = STREAMPROCESSORMANAGER_CYCLES_FOR_DRYRUN; // by then it should have started
529     bool all_dry_running = false;
530     while (!all_dry_running && cnt) {
531         all_dry_running = true;
532         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
533                 it != m_ReceiveProcessors.end();
534                 ++it ) {
535             all_dry_running &= (*it)->isDryRunning();
536         }
537         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
538                 it != m_TransmitProcessors.end();
539                 ++it ) {
540             all_dry_running &= (*it)->isDryRunning();
541         }
542
543         SleepRelativeUsec(125);
544         cnt--;
545     }
546     if(cnt==0) {
547         debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SP's to start dry-running\n");
548         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
549                 it != m_ReceiveProcessors.end();
550                 ++it ) {
551             debugOutput( DEBUG_LEVEL_VERBOSE, " %s SP %p has state %s\n",
552                 (*it)->getTypeString(), *it, (*it)->getStateString());
553         }
554         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
555                 it != m_TransmitProcessors.end();
556                 ++it ) {
557             debugOutput( DEBUG_LEVEL_VERBOSE, " %s SP %p has state %s\n",
558                 (*it)->getTypeString(), *it, (*it)->getStateString());
559         }
560         return false;
561     }
562     debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams dry-running...\n");
563     return true;
564 }
565
566 bool StreamProcessorManager::syncStartAll() {
567     if(m_SyncSource == NULL) return false;
568
569     // get the options
570     int signal_delay_ticks = STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS;
571     int xmit_prebuffer_frames = STREAMPROCESSORMANAGER_XMIT_PREBUFFER_FRAMES;
572     int sync_wait_time_msec = STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC;
573     int cycles_for_startup = STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP;
574     int prestart_cycles_for_xmit = STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_XMIT;
575     int prestart_cycles_for_recv = STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_RECV;
576     Util::Configuration &config = m_parent.getConfiguration();
577     config.getValueForSetting("streaming.spm.signal_delay_ticks", signal_delay_ticks);
578     config.getValueForSetting("streaming.spm.xmit_prebuffer_frames", xmit_prebuffer_frames);
579     config.getValueForSetting("streaming.spm.sync_wait_time_msec", sync_wait_time_msec);
580     config.getValueForSetting("streaming.spm.cycles_for_startup", cycles_for_startup);
581     config.getValueForSetting("streaming.spm.prestart_cycles_for_xmit", prestart_cycles_for_xmit);
582     config.getValueForSetting("streaming.spm.prestart_cycles_for_recv", prestart_cycles_for_recv);
583
584     // figure out when to get the SP's running.
585     // the xmit SP's should also know the base timestamp
586     // streams should be aligned here
587
588     // now find out how long we have to delay the wait operation such that
589     // the received frames will all be presented to the SP
590     debugOutput( DEBUG_LEVEL_VERBOSE, "Finding minimal sync delay...\n");
591     int max_of_min_delay = 0;
592     int min_delay = 0;
593     int packet_size_frames = 0;
594     int max_packet_size_frames = 0;
595
596     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
597             it != m_ReceiveProcessors.end();
598             ++it ) {
599         min_delay = (*it)->getMaxFrameLatency();
600         if(min_delay > max_of_min_delay) max_of_min_delay = min_delay;
601         packet_size_frames = (*it)->getNominalFramesPerPacket();
602         if(packet_size_frames > max_packet_size_frames) max_packet_size_frames = packet_size_frames;
603     }
604     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
605             it != m_TransmitProcessors.end();
606             ++it ) {
607         packet_size_frames = (*it)->getNominalFramesPerPacket();
608         if(packet_size_frames > max_packet_size_frames) max_packet_size_frames = packet_size_frames;
609     }
610     debugOutput( DEBUG_LEVEL_VERBOSE, " max_of_min_delay = %d, max_packet_size_frames = %d...\n", max_of_min_delay, max_packet_size_frames);
611
612     // add some processing margin. This only shifts the time
613     // at which the buffer is transfer()'ed. This makes things somewhat
614     // more robust.
615     m_sync_delay = max_of_min_delay + signal_delay_ticks;
616
617     //STEP X: when we implement such a function, we can wait for a signal from the devices that they
618     //        have acquired lock
619     //debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for device(s) to indicate clock sync lock...\n");
620     //sleep(2); // FIXME: be smarter here
621
622     // make sure that we are dry-running long enough for the
623     // DLL to have a decent sync (FIXME: does the DLL get updated when dry-running)?
624     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n");
625
626     unsigned int nb_sync_runs = (sync_wait_time_msec * getNominalRate());
627     nb_sync_runs /= 1000;
628     nb_sync_runs /= getPeriodSize();
629
630     while(nb_sync_runs--) { // or while not sync-ed?
631         // check if we were woken up too soon
632         uint64_t ticks_at_period = m_SyncSource->getTimeAtPeriod();
633         uint64_t ticks_at_period_margin = ticks_at_period + m_sync_delay;
634         uint64_t pred_system_time_at_xfer = m_SyncSource->getParent().get1394Service().getSystemTimeForCycleTimerTicks(ticks_at_period_margin);
635    
636         #if DEBUG_EXTREME_ENABLE
637         int64_t now = Util::SystemTimeSource::getCurrentTime();
638         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "CTR  pred: %" PRId64 ", syncdelay: %" PRId64 ", diff: %" PRId64 "\n", ticks_at_period, ticks_at_period_margin, ticks_at_period_margin-ticks_at_period );
639         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "PREWAIT  pred: %" PRId64 ", now: %" PRId64 ", wait: %" PRId64 "\n", pred_system_time_at_xfer, now, pred_system_time_at_xfer-now );
640         #endif
641    
642         // wait until it's time to transfer
643         Util::SystemTimeSource::SleepUsecAbsolute(pred_system_time_at_xfer);
644    
645         #if DEBUG_EXTREME_ENABLE
646         now = Util::SystemTimeSource::getCurrentTime();
647         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "POSTWAIT pred: %" PRId64 ", now: %" PRId64 ", excess: %" PRId64 "\n", pred_system_time_at_xfer, now, now-pred_system_time_at_xfer );
648         #endif
649     }
650
651     debugOutput( DEBUG_LEVEL_VERBOSE, "Propagate sync info...\n");
652     // FIXME: in the SPM it would be nice to have system time instead of
653     //        1394 time
654
655     float syncrate = 0.0;
656     float tpf = m_SyncSource->getTicksPerFrame();
657     if (tpf > 0.0) {
658         syncrate = 24576000.0/tpf;
659     } else {
660         debugWarning("tpf <= 0? %f\n", tpf);
661     }
662     debugOutput( DEBUG_LEVEL_VERBOSE, " sync source frame rate: %f fps (%f tpf)\n", syncrate, tpf);
663
664     // we now should have decent sync info on the sync source
665     // determine a point in time where the system should start
666     // figure out where we are now
667     uint64_t time_of_first_sample = m_SyncSource->getTimeAtPeriod();
668     debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
669         time_of_first_sample,
670         (unsigned int)TICKS_TO_SECS(time_of_first_sample),
671         (unsigned int)TICKS_TO_CYCLES(time_of_first_sample),
672         (unsigned int)TICKS_TO_OFFSET(time_of_first_sample));
673
674     // start wet-running in STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP cycles
675     // this is the time window we have to setup all SP's such that they
676     // can start wet-running correctly.
677     // we have to round this time to an integer number of audio packets
678     double time_for_startup_abs = (double)(cycles_for_startup * TICKS_PER_CYCLE);
679     int time_for_startup_frames = (int)(time_for_startup_abs / tpf);
680     time_for_startup_frames = ((time_for_startup_frames / max_packet_size_frames) + 1) * max_packet_size_frames;
681     uint64_t time_for_startup_ticks = (uint64_t)((float)time_for_startup_frames * tpf);
682
683     time_of_first_sample = addTicks(time_of_first_sample,
684                                     time_for_startup_ticks);
685     debugOutput( DEBUG_LEVEL_VERBOSE, "  add %d frames (%011" PRIu64 " ticks)...\n",
686         time_for_startup_frames, time_for_startup_ticks);
687
688     debugOutput( DEBUG_LEVEL_VERBOSE, "  => first sample at TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
689         time_of_first_sample,
690         (unsigned int)TICKS_TO_SECS(time_of_first_sample),
691         (unsigned int)TICKS_TO_CYCLES(time_of_first_sample),
692         (unsigned int)TICKS_TO_OFFSET(time_of_first_sample));
693
694     // we should start wet-running the transmit SP's some cycles in advance
695     // such that we know it is wet-running when it should output its first sample
696     uint64_t time_to_start_xmit = substractTicks(time_of_first_sample,
697                                                  prestart_cycles_for_xmit * TICKS_PER_CYCLE);
698
699     uint64_t time_to_start_recv = substractTicks(time_of_first_sample,
700                                                  prestart_cycles_for_recv * TICKS_PER_CYCLE);
701     debugOutput( DEBUG_LEVEL_VERBOSE, "  => xmit starts at  TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
702         time_to_start_xmit,
703         (unsigned int)TICKS_TO_SECS(time_to_start_xmit),
704         (unsigned int)TICKS_TO_CYCLES(time_to_start_xmit),
705         (unsigned int)TICKS_TO_OFFSET(time_to_start_xmit));
706     debugOutput( DEBUG_LEVEL_VERBOSE, "  => recv starts at  TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
707         time_to_start_recv,
708         (unsigned int)TICKS_TO_SECS(time_to_start_recv),
709         (unsigned int)TICKS_TO_CYCLES(time_to_start_recv),
710         (unsigned int)TICKS_TO_OFFSET(time_to_start_recv));
711
712     // print the sync delay
713     int sync_delay_frames = (int)((float)m_sync_delay / m_SyncSource->getTicksPerFrame());
714     debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay: %d = %d + %d ticks (%03us %04uc %04ut) [%d frames]...\n",
715         m_sync_delay, max_of_min_delay, signal_delay_ticks,
716         (unsigned int)TICKS_TO_SECS(m_sync_delay),
717         (unsigned int)TICKS_TO_CYCLES(m_sync_delay),
718         (unsigned int)TICKS_TO_OFFSET(m_sync_delay),
719         sync_delay_frames);
720
721     // the amount of prebuffer frames should be a multiple of the common block size
722     // as otherwise the position of MIDI is messed up
723     if(xmit_prebuffer_frames % max_packet_size_frames) {
724         int tmp = 0;
725         while(tmp < xmit_prebuffer_frames) {
726             tmp += max_packet_size_frames;
727         }
728         debugOutput(DEBUG_LEVEL_VERBOSE,
729                     "The number of prebuffer frames (%d) is not a multiple of the common block size (%d), increased to %d...\n",
730                     xmit_prebuffer_frames, max_packet_size_frames, tmp);
731         xmit_prebuffer_frames = tmp;
732     }
733
734     // check if this can even work.
735     // the worst case point where we can receive a period is at 1 period + sync delay
736     // this means that the number of frames in the xmit buffer has to be at least
737     // 1 period + sync delay
738     if(xmit_prebuffer_frames + m_period * m_nb_buffers < m_period + sync_delay_frames) {
739         debugWarning("The amount of transmit buffer frames (%d) is too small (< %d). "
740                      "This will most likely cause xruns.\n",
741                      xmit_prebuffer_frames + m_period * m_nb_buffers,
742                      m_period + sync_delay_frames);
743     }
744
745     // at this point the buffer head timestamp of the transmit buffers can be set
746     // this is the presentation time of the first sample in the buffer
747     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
748           it != m_TransmitProcessors.end();
749           ++it ) {
750         // set the number of prebuffer frames
751         (*it)->setExtraBufferFrames(xmit_prebuffer_frames);
752
753         // set the TSP of the first sample in the buffer
754         (*it)->setBufferHeadTimestamp(time_of_first_sample);
755         ffado_timestamp_t ts;
756         signed int fc;
757         (*it)->getBufferHeadTimestamp ( &ts, &fc );
758         debugOutput( DEBUG_LEVEL_VERBOSE, " transmit buffer tail %010" PRId64 " => head TS %010" PRIu64 ", fc=%d...\n",
759                     time_of_first_sample, (uint64_t)ts, fc);
760     }
761
762     // the receive processors can be delayed by sync_delay ticks
763     // this means that in the worst case we have to be able to accomodate
764     // an extra sync_delay ticks worth of frames in the receive SP buffer
765     // the sync delay should be rounded to an integer amount of max_packet_size
766     int tmp = sync_delay_frames / max_packet_size_frames;
767     tmp = tmp + 1;
768     sync_delay_frames = tmp * max_packet_size_frames;
769     if (sync_delay_frames < 1024) sync_delay_frames = 1024; //HACK
770
771     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
772           it != m_ReceiveProcessors.end();
773           ++it ) {
774         // set the number of extra buffer frames
775         (*it)->setExtraBufferFrames(sync_delay_frames);
776     }
777
778     // switch syncsource to running state
779     uint64_t time_to_start_sync;
780     // FIXME: this is most likely not going to work for transmit sync sources
781     // but those are unsupported in this version
782     if(m_SyncSource->getType() == StreamProcessor::ePT_Receive ) {
783         time_to_start_sync = time_to_start_recv;
784     } else {
785         time_to_start_sync = time_to_start_xmit;
786     }
787     if(!m_SyncSource->scheduleStartRunning(time_to_start_sync)) {
788         debugError("m_SyncSource->scheduleStartRunning(%11" PRIu64 ") failed\n", time_to_start_sync);
789         return false;
790     }
791
792     // STEP X: switch all non-syncsource SP's over to the running state
793     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
794           it != m_ReceiveProcessors.end();
795           ++it ) {
796         if(*it != m_SyncSource) {
797             if(!(*it)->scheduleStartRunning(time_to_start_recv)) {
798                 debugError("%p->scheduleStartRunning(%11" PRIu64 ") failed\n", *it, time_to_start_recv);
799                 return false;
800             }
801         }
802     }
803     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
804           it != m_TransmitProcessors.end();
805           ++it ) {
806         if(*it != m_SyncSource) {
807             if(!(*it)->scheduleStartRunning(time_to_start_xmit)) {
808                 debugError("%p->scheduleStartRunning(%11" PRIu64 ") failed\n", *it, time_to_start_xmit);
809                 return false;
810             }
811         }
812     }
813     // wait for the syncsource to start running.
814     // that will block the waitForPeriod call until everyone has started (theoretically)
815     // note: the SP's are scheduled to start in STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP cycles,
816     // so a 20 times this value should be a good timeout
817     //int cnt = cycles_for_startup * 20; // by then it should have started
818     // or maybe we just have to use 1 second, as this wraps the cycle counter
819     int cnt = 8000;
820     while (!m_SyncSource->isRunning() && cnt) {
821         SleepRelativeUsec(125);
822         cnt--;
823     }
824     if(cnt==0) {
825         debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SyncSource to get started\n");
826         return false;
827     }
828
829     // the sync source is running, we can now read a decent received timestamp from it
830     m_time_of_transfer = m_SyncSource->getTimeAtPeriod();
831
832     // and a (rough) approximation of the rate
833     float rate = m_SyncSource->getTicksPerFrame();
834
835     #ifdef DEBUG
836     // the time at which the previous period would have passed
837     m_time_of_transfer2 = m_time_of_transfer;
838     m_time_of_transfer2 = substractTicks(m_time_of_transfer2, (uint64_t)(m_period * rate));
839     #endif
840
841     debugOutput( DEBUG_LEVEL_VERBOSE, "  initial time of transfer %010" PRId64 ", rate %f...\n",
842                 m_time_of_transfer, rate);
843
844     // FIXME: ideally we'd want the SP itself to account for the xmit_prebuffer_frames
845     // but that would also require to use a different approach to setting the initial TSP's
846     int64_t delay_in_ticks = (int64_t)(((float)((m_nb_buffers-1) * m_period + xmit_prebuffer_frames)) * rate);
847
848     // then use this information to initialize the xmit handlers
849
850     //  we now set the buffer tail timestamp of the transmit buffer
851     //  to the period transfer time instant plus what's nb_buffers - 1
852     //  in ticks. This due to the fact that we (should) have received one period
853     //  worth of ticks at t = m_time_of_transfer
854     //  hence one period of frames should also have been transmitted, which means
855     //  that there should be (nb_buffers - 1) * periodsize of frames in the xmit buffer
856     //  there are also xmit_prebuffer_frames frames extra present in the buffer
857     //  that allows us to calculate the tail timestamp for the buffer.
858
859     int64_t transmit_tail_timestamp = addTicks(m_time_of_transfer, delay_in_ticks);
860     debugOutput( DEBUG_LEVEL_VERBOSE, "  preset transmit tail TS %010" PRId64 ", rate %f...\n",
861                 transmit_tail_timestamp, rate);
862
863     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
864         it != m_TransmitProcessors.end();
865         ++it ) {
866         (*it)->setTicksPerFrame(rate);
867         (*it)->setBufferTailTimestamp(transmit_tail_timestamp);
868         ffado_timestamp_t ts;
869         signed int fc;
870         (*it)->getBufferHeadTimestamp ( &ts, &fc );
871         debugOutput( DEBUG_LEVEL_VERBOSE, "   => transmit head TS %010" PRId64 ", fc=%d...\n",
872                     (uint64_t)ts, fc);
873     }
874
875     // align the received streams to be phase aligned
876     if(!alignReceivedStreams()) {
877         debugError("Could not align streams...\n");
878         return false;
879     }
880
881     debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams running...\n");
882     return true;
883 }
884
885 bool
886 StreamProcessorManager::alignReceivedStreams()
887 {
888     debugOutput( DEBUG_LEVEL_VERBOSE, "Aligning received streams...\n");
889     unsigned int nb_sync_runs;
890     unsigned int nb_rcv_sp = m_ReceiveProcessors.size();
891     int64_t diff_between_streams[nb_rcv_sp];
892     int64_t diff;
893
894     unsigned int i;
895
896     int cnt = STREAMPROCESSORMANAGER_NB_ALIGN_TRIES;
897     int align_average_time_msec = STREAMPROCESSORMANAGER_ALIGN_AVERAGE_TIME_MSEC;
898     Util::Configuration &config = m_parent.getConfiguration();
899     config.getValueForSetting("streaming.spm.align_tries", cnt);
900     config.getValueForSetting("streaming.spm.align_average_time_msec", align_average_time_msec);
901
902     unsigned int periods_per_align_try = (align_average_time_msec * getNominalRate());
903     periods_per_align_try /= 1000;
904     periods_per_align_try /= getPeriodSize();
905     debugOutput( DEBUG_LEVEL_VERBOSE, " averaging over %u periods...\n", periods_per_align_try);
906
907     bool aligned = false;
908     while (!aligned && cnt--) {
909         nb_sync_runs = periods_per_align_try;
910         while(nb_sync_runs) {
911             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " check (%d)...\n", nb_sync_runs);
912             if(!waitForPeriod()) {
913                 debugWarning("xrun while aligning streams...\n");
914                 return false;
915             }
916
917             // before we do anything else, transfer
918             if(!transferSilence()) {
919                 debugError("Could not transfer silence\n");
920                 return false;
921             }
922
923             // now calculate the stream offset
924             i = 0;
925             for ( i = 0; i < nb_rcv_sp; i++) {
926                 StreamProcessor *s = m_ReceiveProcessors.at(i);
927                 diff = diffTicks(m_SyncSource->getTimeAtPeriod(), s->getTimeAtPeriod());
928                 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "  offset between SyncSP %p and SP %p is %" PRId64 " ticks...\n",
929                     m_SyncSource, s, diff);
930                 if ( nb_sync_runs == periods_per_align_try ) {
931                     diff_between_streams[i] = diff;
932                 } else {
933                     diff_between_streams[i] += diff;
934                 }
935             }
936
937             nb_sync_runs--;
938         }
939         // calculate the average offsets
940         debugOutput( DEBUG_LEVEL_VERBOSE, " Average offsets:\n");
941         int diff_between_streams_frames[nb_rcv_sp];
942         aligned = true;
943
944         // first find whether the streams are aligned and what their offset is
945         for ( i = 0; i < nb_rcv_sp; i++) {
946             StreamProcessor *s = m_ReceiveProcessors.at(i);
947
948             diff_between_streams[i] /= periods_per_align_try;
949             diff_between_streams_frames[i] = (int)roundf(diff_between_streams[i] / s->getTicksPerFrame());
950             debugOutput( DEBUG_LEVEL_VERBOSE, "   avg offset between SyncSP %p and SP %p is %" PRId64 " ticks, %d frames...\n",
951                 m_SyncSource, s, diff_between_streams[i], diff_between_streams_frames[i]);
952
953             aligned &= (diff_between_streams_frames[i] == 0);
954         }
955
956         // if required, align the streams
957         int frames_to_shift_stream[nb_rcv_sp];
958         int min_shift = 9999;
959         if (!aligned) {
960             // find the minimum value (= earliest stream)
961             for ( i = 0; i < nb_rcv_sp; i++) {
962                 if (diff_between_streams_frames[i] < min_shift) {
963                     min_shift = diff_between_streams_frames[i];
964                 }
965             }
966             debugOutput( DEBUG_LEVEL_VERBOSE, " correcting shift with %d frames\n", min_shift);
967             // ensure that the streams are shifted only in the 'positive' direction
968             // i.e. that frames are only dropped, not added since that results
969             // in multiple writers for the data ringbuffer
970             // this also results in 'minimal shift' (not that it's required since the
971             // sync SP is part of the SP set)
972             for ( i = 0; i < nb_rcv_sp; i++) {
973                 frames_to_shift_stream[i] = diff_between_streams_frames[i] - min_shift;
974                 debugOutput(DEBUG_LEVEL_VERBOSE,
975                             "  going to drop %03d frames from stream %d\n",
976                             frames_to_shift_stream[i], i);
977             }
978             // perform the actual shift
979             for ( i = 0; i < nb_rcv_sp; i++) {
980                 StreamProcessor *s = m_ReceiveProcessors.at(i);
981                 // reposition the stream
982                 if(!s->shiftStream(frames_to_shift_stream[i])) {
983                     debugError("Could not shift SP %p %d frames\n", s, frames_to_shift_stream[i]);
984                     return false;
985                 }
986             }
987         }
988
989         if (!aligned) {
990             debugOutput(DEBUG_LEVEL_VERBOSE, "Streams not aligned, doing new round...\n");
991         }
992     }
993     if (cnt == 0) {
994         debugError("Align failed\n");
995         return false;
996     }
997     return true;
998 }
999
1000 bool StreamProcessorManager::start() {
1001     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting Processors...\n");
1002
1003     // start all SP's synchonized
1004     bool start_result = false;
1005     for (int ntries=0; ntries < STREAMPROCESSORMANAGER_SYNCSTART_TRIES; ntries++) {
1006         // put all SP's into dry-running state
1007         if (!startDryRunning()) {
1008             debugOutput(DEBUG_LEVEL_VERBOSE, "Could not put SP's in dry-running state (try %d)\n", ntries);
1009             start_result = false;
1010             continue;
1011         }
1012
1013         start_result = syncStartAll();
1014         if(start_result) {
1015             break;
1016         } else {
1017             debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries);
1018             if(m_shutdown_needed) {
1019                 debugOutput(DEBUG_LEVEL_VERBOSE, "Some fatal error occurred, stop trying.\n");
1020                 return false;
1021             }
1022         }
1023     }
1024     if (!start_result) {
1025         debugFatal("Could not syncStartAll...\n");
1026         // If unable to start, ensure stream processors and their handlers
1027         // are in the stopped state, which is what the caller would reasonably
1028         // expect if start() fails.
1029         stop();
1030         return false;
1031     }
1032     debugOutput( DEBUG_LEVEL_VERBOSE, " Started...\n");
1033     return true;
1034 }
1035
1036 bool StreamProcessorManager::stop() {
1037     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping...\n");
1038
1039     debugOutput( DEBUG_LEVEL_VERBOSE, " scheduling stop for all SP's...\n");
1040     // switch SP's over to the dry-running state
1041     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1042           it != m_ReceiveProcessors.end();
1043           ++it ) {
1044         if((*it)->isRunning()) {
1045             if(!(*it)->scheduleStopRunning(-1)) {
1046                 debugError("%p->scheduleStopRunning(-1) failed\n", *it);
1047                 return false;
1048             }
1049         }
1050     }
1051     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1052           it != m_TransmitProcessors.end();
1053           ++it ) {
1054         if((*it)->isRunning()) {
1055             if(!(*it)->scheduleStopRunning(-1)) {
1056                 debugError("%p->scheduleStopRunning(-1) failed\n", *it);
1057                 return false;
1058             }
1059         }
1060     }
1061     // wait for the SP's to get into the dry-running/stopped state
1062     int cnt = 8000;
1063     bool ready = false;
1064     while (!ready && cnt) {
1065         ready = true;
1066         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1067             it != m_ReceiveProcessors.end();
1068             ++it ) {
1069             ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError());
1070         }
1071         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1072             it != m_TransmitProcessors.end();
1073             ++it ) {
1074             ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError());
1075         }
1076         SleepRelativeUsec(125);
1077         cnt--;
1078     }
1079     if(cnt==0) {
1080         debugWarning(" Timeout waiting for the SP's to start dry-running\n");
1081         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1082             it != m_ReceiveProcessors.end();
1083             ++it ) {
1084             (*it)->dumpInfo();
1085         }
1086         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1087             it != m_TransmitProcessors.end();
1088             ++it ) {
1089             (*it)->dumpInfo();
1090         }
1091         return false;
1092     }
1093
1094     // switch SP's over to the stopped state
1095     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1096           it != m_ReceiveProcessors.end();
1097           ++it ) {
1098         if ((*it)->inError()) {
1099             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it);
1100         } else if(!(*it)->scheduleStopDryRunning(-1)) {
1101             debugError("%p->scheduleStopDryRunning(-1) failed\n", *it);
1102             return false;
1103         }
1104     }
1105     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1106           it != m_TransmitProcessors.end();
1107           ++it ) {
1108         if ((*it)->inError()) {
1109             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it);
1110         } else if(!(*it)->scheduleStopDryRunning(-1)) {
1111             debugError("%p->scheduleStopDryRunning(-1) failed\n", *it);
1112             return false;
1113         }
1114     }
1115     // wait for the SP's to get into the stopped state
1116     cnt = 8000;
1117     ready = false;
1118     while (!ready && cnt) {
1119         ready = true;
1120         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1121             it != m_ReceiveProcessors.end();
1122             ++it ) {
1123             ready &= ((*it)->isStopped() || (*it)->inError());
1124         }
1125         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1126             it != m_TransmitProcessors.end();
1127             ++it ) {
1128             ready &= ((*it)->isStopped() || (*it)->inError());
1129         }
1130         SleepRelativeUsec(125);
1131         cnt--;
1132     }
1133     if(cnt==0) {
1134         debugWarning(" Timeout waiting for the SP's to stop\n");
1135         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1136             it != m_ReceiveProcessors.end();
1137             ++it ) {
1138             (*it)->dumpInfo();
1139         }
1140         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1141             it != m_TransmitProcessors.end();
1142             ++it ) {
1143             (*it)->dumpInfo();
1144         }
1145         return false;
1146     }
1147     debugOutput( DEBUG_LEVEL_VERBOSE, " Stopped...\n");
1148     return true;
1149 }
1150
1151 /**
1152  * Called upon Xrun events. This brings all StreamProcessors back
1153  * into their starting state, and then carries on streaming. This should
1154  * have the same effect as restarting the whole thing.
1155  *
1156  * @return true if successful, false otherwise
1157  */
1158 bool StreamProcessorManager::handleXrun() {
1159
1160     debugOutput( DEBUG_LEVEL_VERBOSE, "Handling Xrun ...\n");
1161
1162     dumpInfo();
1163
1164     /*
1165      * Reset means:
1166      * 1) Disabling the SP's, so that they don't process any packets
1167      *    note: the isomanager does keep on delivering/requesting them
1168      * 2) Bringing all buffers & streamprocessors into a know state
1169      *    - Clear all capture buffers
1170      *    - Put nb_periods*period_size of null frames into the playback buffers
1171      * 3) Re-enable the SP's
1172      */
1173
1174     debugOutput( DEBUG_LEVEL_VERBOSE, "Restarting StreamProcessors...\n");
1175     // start all SP's synchonized
1176     bool start_result = false;
1177     for (int ntries=0; ntries < STREAMPROCESSORMANAGER_SYNCSTART_TRIES; ntries++) {
1178         if(m_shutdown_needed) {
1179             debugOutput(DEBUG_LEVEL_VERBOSE, "Shutdown requested...\n");
1180             return true;
1181         }
1182         // put all SP's into dry-running state
1183         if (!startDryRunning()) {
1184             debugShowBackLog();
1185             debugOutput(DEBUG_LEVEL_VERBOSE, "Could not put SP's in dry-running state (try %d)\n", ntries);
1186             start_result = false;
1187             continue;
1188         }
1189
1190         start_result = syncStartAll();
1191         if(start_result) {
1192             break;
1193         } else {
1194             debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries);
1195         }
1196     }
1197     if (!start_result) {
1198         debugFatal("Could not syncStartAll...\n");
1199         return false;
1200     }
1201     debugOutput( DEBUG_LEVEL_VERBOSE, "Xrun handled...\n");
1202
1203     return true;
1204 }
1205
1206 /**
1207  * @brief Waits until the next period of samples is ready
1208  *
1209  * This function does not return until a full period of samples is (or should be)
1210  * ready to be transferred.
1211  *
1212  * @return true if the period is ready, false if not
1213  */
1214 bool StreamProcessorManager::waitForPeriod() {
1215     if(m_SyncSource == NULL) return false;
1216     if(m_shutdown_needed) return false;
1217     bool xrun_occurred = false;
1218     bool in_error = false;
1219
1220     // grab the wait lock
1221     // this ensures that bus reset handling doesn't interfere
1222     Util::MutexLockHelper lock(*m_WaitLock);
1223     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
1224                         "waiting for period (%d frames in buffer)...\n",
1225                         m_SyncSource->getBufferFill());
1226     uint64_t ticks_at_period = m_SyncSource->getTimeAtPeriod();
1227     uint64_t ticks_at_period_margin = ticks_at_period + m_sync_delay;
1228     uint64_t pred_system_time_at_xfer = m_SyncSource->getParent().get1394Service().getSystemTimeForCycleTimerTicks(ticks_at_period_margin);
1229
1230     #if DEBUG_EXTREME_ENABLE
1231     int64_t now = Util::SystemTimeSource::getCurrentTime();
1232     debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "CTR  pred: %" PRId64 ", syncdelay: %" PRId64 ", diff: %" PRId64 "\n", ticks_at_period, ticks_at_period_margin, ticks_at_period_margin-ticks_at_period );
1233     debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "PREWAIT  pred: %" PRId64 ", now: %" PRId64 ", wait: %" PRId64 "\n", pred_system_time_at_xfer, now, pred_system_time_at_xfer-now );
1234     #endif
1235
1236     // wait until it's time to transfer
1237     Util::SystemTimeSource::SleepUsecAbsolute(pred_system_time_at_xfer);
1238
1239     #if DEBUG_EXTREME_ENABLE
1240     now = Util::SystemTimeSource::getCurrentTime();
1241     debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "POSTWAIT pred: %" PRId64 ", now: %" PRId64 ", excess: %" PRId64 "\n", pred_system_time_at_xfer, now, now-pred_system_time_at_xfer );
1242     #endif
1243
1244     // the period should be ready now
1245     #if DEBUG_EXTREME_ENABLE
1246     int rcv_fills[10];
1247     int xmt_fills[10];
1248     int i;
1249     i=0;
1250     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1251         it != m_ReceiveProcessors.end();
1252         ++it ) {
1253         rcv_fills[i] = (*it)->getBufferFill();
1254         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "RECV SP %p bufferfill: %05d\n", *it, rcv_fills[i]);
1255         i++;
1256     }
1257     i=0;
1258     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1259         it != m_TransmitProcessors.end();
1260         ++it ) {
1261         xmt_fills[i] = (*it)->getBufferFill();
1262         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "XMIT SP %p bufferfill: %05d\n", *it, xmt_fills[i]);
1263         i++;
1264     }
1265     for(i=0;i<1;i++) {
1266         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "SP %02d RECV: %05d [%05d] XMIT: %05d [%05d] DIFF: %05d\n", i,
1267                     rcv_fills[i], rcv_fills[i] - m_period,
1268                     xmt_fills[i], xmt_fills[i] - m_period,
1269                     rcv_fills[i] - xmt_fills[i]);
1270     }
1271     #endif
1272
1273     #if STREAMPROCESSORMANAGER_ALLOW_DELAYED_PERIOD_SIGNAL
1274     // HACK: we force wait until every SP is ready. this is needed
1275     // since the raw1394 interface provides no control over interrupts
1276     // resulting in very bad predictability on when the data is present.
1277     bool period_not_ready = true;
1278     while(period_not_ready) {
1279         period_not_ready = false;
1280         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1281             it != m_ReceiveProcessors.end();
1282             ++it ) {
1283             bool this_sp_period_ready = (*it)->canConsumePeriod();
1284             if (!this_sp_period_ready) {
1285                 period_not_ready = true;
1286             }
1287         }
1288         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1289             it != m_TransmitProcessors.end();
1290             ++it ) {
1291             bool this_sp_period_ready = (*it)->canProducePeriod();
1292             if (!this_sp_period_ready) {
1293                 period_not_ready = true;
1294             }
1295         }
1296
1297         if (period_not_ready) {
1298             debugOutput(DEBUG_LEVEL_VERBOSE, " wait extended since period not ready...\n");
1299             Util::SystemTimeSource::SleepUsecRelative(125); // one cycle
1300         }
1301
1302         // check for underruns/errors on the ISO side,
1303         // those should make us bail out of the wait loop
1304         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1305             it != m_ReceiveProcessors.end();
1306             ++it ) {
1307             // a xrun has occurred on the Iso side
1308             xrun_occurred |= (*it)->xrunOccurred();
1309             in_error |= (*it)->inError();
1310         }
1311         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1312             it != m_TransmitProcessors.end();
1313             ++it ) {
1314             // a xrun has occurred on the Iso side
1315             xrun_occurred |= (*it)->xrunOccurred();
1316             in_error |= (*it)->inError();
1317         }
1318         if(xrun_occurred | in_error | m_shutdown_needed) break;
1319     }
1320     #else
1321     // check for underruns/errors on the ISO side,
1322     // those should make us bail out of the wait loop
1323     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1324         it != m_ReceiveProcessors.end();
1325         ++it ) {
1326         // xrun on data buffer side
1327         if (!(*it)->canConsumePeriod()) {
1328             xrun_occurred = true;
1329         }
1330         // a xrun has occurred on the Iso side
1331         xrun_occurred |= (*it)->xrunOccurred();
1332         in_error |= (*it)->inError();
1333     }
1334     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1335         it != m_TransmitProcessors.end();
1336         ++it ) {
1337         // xrun on data buffer side
1338         if (!(*it)->canProducePeriod()) {
1339             xrun_occurred = true;
1340         }
1341         // a xrun has occurred on the Iso side
1342         xrun_occurred |= (*it)->xrunOccurred();
1343         in_error |= (*it)->inError();
1344     }
1345     #endif
1346
1347     if(xrun_occurred) {
1348         debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to xrun...\n");
1349     }
1350     if(in_error) {
1351         debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to error...\n");
1352         m_shutdown_needed = true;
1353     }
1354
1355     // we save the 'ideal' time of the transfer at this point,
1356     // because we can have interleaved read - process - write
1357     // cycles making that we modify a receiving stream's buffer
1358     // before we get to writing.
1359     // NOTE: before waitForPeriod() is called again, both the transmit
1360     //       and the receive processors should have done their transfer.
1361     m_time_of_transfer = m_SyncSource->getTimeAtPeriod();
1362    
1363     #ifdef DEBUG
1364     int ticks_per_period = (int)(m_SyncSource->getTicksPerFrame() * m_period);
1365    
1366     int diff = diffTicks(m_time_of_transfer, m_time_of_transfer2);
1367     // display message if the difference between two successive tick
1368     // values is more than 50 ticks. 1 sample at 48k is 512 ticks
1369     // so 50 ticks = 10%, which is a rather large jitter value.
1370     if(diff-ticks_per_period > m_max_diff_ticks || diff-ticks_per_period < -m_max_diff_ticks) {
1371         debugOutput(DEBUG_LEVEL_VERBOSE, "rather large TSP difference TS=%011" PRIu64 " => TS=%011" PRIu64 " (%d, nom %d)\n",
1372                                             m_time_of_transfer2, m_time_of_transfer, diff, ticks_per_period);
1373     }
1374     m_time_of_transfer2 = m_time_of_transfer;
1375     #endif
1376
1377     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
1378                         "transfer period %d at %" PRIu64 " ticks...\n",
1379                         m_nbperiods, m_time_of_transfer);
1380
1381     #if DEBUG_EXTREME_ENABLE
1382     int rcv_bf=0, xmt_bf=0;
1383     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1384         it != m_ReceiveProcessors.end();
1385         ++it ) {
1386         rcv_bf = (*it)->getBufferFill();
1387     }
1388     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1389         it != m_TransmitProcessors.end();
1390         ++it ) {
1391         xmt_bf = (*it)->getBufferFill();
1392     }
1393     debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE,
1394                         "XF at %011" PRIu64 " ticks, RBF=%d, XBF=%d, SUM=%d...\n",
1395                         m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf);
1396     #endif
1397
1398     #ifdef DEBUG
1399     // check if xruns occurred on the Iso side.
1400     // also check if xruns will occur should we transfer() now
1401     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1402           it != m_ReceiveProcessors.end();
1403           ++it ) {
1404
1405         if ((*it)->xrunOccurred()) {
1406             debugOutput(DEBUG_LEVEL_NORMAL,
1407                         "Xrun on RECV SP %p due to ISO side xrun\n", *it);
1408             (*it)->dumpInfo();
1409         }
1410         if (!((*it)->canClientTransferFrames(m_period))) {
1411             debugOutput(DEBUG_LEVEL_NORMAL,
1412                         "Xrun on RECV SP %p due to buffer side xrun\n", *it);
1413             (*it)->dumpInfo();
1414         }
1415     }
1416     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1417           it != m_TransmitProcessors.end();
1418           ++it ) {
1419         if ((*it)->xrunOccurred()) {
1420             debugOutput(DEBUG_LEVEL_NORMAL,
1421                         "Xrun on XMIT SP %p due to ISO side xrun\n", *it);
1422         }
1423         if (!((*it)->canClientTransferFrames(m_period))) {
1424             debugOutput(DEBUG_LEVEL_NORMAL,
1425                         "Xrun on XMIT SP %p due to buffer side xrun\n", *it);
1426         }
1427     }
1428     #endif
1429     m_nbperiods++;
1430
1431     // this is to notify the client of the delay that we introduced by waiting
1432     pred_system_time_at_xfer = m_SyncSource->getParent().get1394Service().getSystemTimeForCycleTimerTicks(m_time_of_transfer);
1433
1434     m_delayed_usecs = Util::SystemTimeSource::getCurrentTime() - pred_system_time_at_xfer;
1435     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
1436                         "delayed for %d usecs...\n",
1437                         m_delayed_usecs);
1438
1439     // now we can signal the client that we are (should be) ready
1440     return !xrun_occurred;
1441 }
1442
1443 /**
1444  * @brief Transfer one period of frames for both receive and transmit StreamProcessors
1445  *
1446  * Transfers one period of frames from the client side to the Iso side and vice versa.
1447  *
1448  * @return true if successful, false otherwise (indicates xrun).
1449  */
1450 bool StreamProcessorManager::transfer() {
1451     debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
1452     bool retval=true;
1453     retval &= transfer(StreamProcessor::ePT_Receive);
1454     retval &= transfer(StreamProcessor::ePT_Transmit);
1455     return retval;
1456 }
1457
1458 /**
1459  * @brief Transfer one period of frames for either the receive or transmit StreamProcessors
1460  *
1461  * Transfers one period of frames from the client side to the Iso side or vice versa.
1462  *
1463  * @param t The processor type to tranfer for (receive or transmit)
1464  * @return true if successful, false otherwise (indicates xrun).
1465  */
1466 bool StreamProcessorManager::transfer(enum StreamProcessor::eProcessorType t) {
1467     if(m_SyncSource == NULL) return false;
1468     debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE,
1469         "transfer(%d) at TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
1470         t, m_time_of_transfer,
1471         (unsigned int)TICKS_TO_SECS(m_time_of_transfer),
1472         (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer),
1473         (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer));
1474
1475     bool retval = true;
1476     // a static cast could make sure that there is no performance
1477     // penalty for the virtual functions (to be checked)
1478     if (t==StreamProcessor::ePT_Receive) {
1479         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1480                 it != m_ReceiveProcessors.end();
1481                 ++it ) {
1482             if(!(*it)->getFrames(m_period, m_time_of_transfer)) {
1483                     debugWarning("could not getFrames(%u, %11" PRIu64 ") from stream processor (%p)\n",
1484                             m_period, m_time_of_transfer,*it);
1485                 retval &= false; // buffer underrun
1486             }
1487         }
1488     } else {
1489         // FIXME: in the SPM it would be nice to have system time instead of
1490         //        1394 time
1491         float rate = m_SyncSource->getTicksPerFrame();
1492
1493         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1494                 it != m_TransmitProcessors.end();
1495                 ++it ) {
1496             // this is the delay in frames between the point where a frame is received and
1497             // when it is transmitted again
1498             unsigned int one_ringbuffer_in_frames = m_nb_buffers * m_period + (*it)->getExtraBufferFrames();
1499             int64_t one_ringbuffer_in_ticks = (int64_t)(((float)one_ringbuffer_in_frames) * rate);
1500    
1501             // the data we are putting into the buffer is intended to be transmitted
1502             // one ringbuffer size after it has been received
1503             int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks);
1504
1505             if(!(*it)->putFrames(m_period, transmit_timestamp)) {
1506                 debugWarning("could not putFrames(%u,%" PRIu64 ") to stream processor (%p)\n",
1507                         m_period, transmit_timestamp, *it);
1508                 retval &= false; // buffer underrun
1509             }
1510         }
1511     }
1512     return retval;
1513 }
1514
1515 /**
1516  * @brief Transfer one period of silence for both receive and transmit StreamProcessors
1517  *
1518  * Transfers one period of silence to the Iso side for transmit SP's
1519  * or dump one period of frames for receive SP's
1520  *
1521  * @return true if successful, false otherwise (indicates xrun).
1522  */
1523 bool StreamProcessorManager::transferSilence() {
1524     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Transferring silent period...\n");
1525     bool retval=true;
1526     // NOTE: the order here is opposite from the order in
1527     // normal operation (transmit is before receive), because
1528     // we can do that here (data=silence=available) and
1529     // it increases reliability (esp. on startup)
1530     retval &= transferSilence(StreamProcessor::ePT_Transmit);
1531     retval &= transferSilence(StreamProcessor::ePT_Receive);
1532     return retval;
1533 }
1534
1535 /**
1536  * @brief Transfer one period of silence for either the receive or transmit StreamProcessors
1537  *
1538  * Transfers one period of silence to the Iso side for transmit SP's
1539  * or dump one period of frames for receive SP's
1540  *
1541  * @param t The processor type to tranfer for (receive or transmit)
1542  * @return true if successful, false otherwise (indicates xrun).
1543  */
1544 bool StreamProcessorManager::transferSilence(enum StreamProcessor::eProcessorType t) {
1545     if(m_SyncSource == NULL) return false;
1546     debugOutput( DEBUG_LEVEL_VERY_VERBOSE,
1547         "transferSilence(%d) at TS=%011" PRIu64 " (%03us %04uc %04ut)...\n",
1548         t, m_time_of_transfer,
1549         (unsigned int)TICKS_TO_SECS(m_time_of_transfer),
1550         (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer),
1551         (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer));
1552
1553     bool retval = true;
1554     // a static cast could make sure that there is no performance
1555     // penalty for the virtual functions (to be checked)
1556     if (t==StreamProcessor::ePT_Receive) {
1557         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1558                 it != m_ReceiveProcessors.end();
1559                 ++it ) {
1560             if(!(*it)->dropFrames(m_period, m_time_of_transfer)) {
1561                     debugWarning("could not dropFrames(%u, %11" PRIu64 ") from stream processor (%p)\n",
1562                             m_period, m_time_of_transfer,*it);
1563                 retval &= false; // buffer underrun
1564             }
1565         }
1566     } else {
1567         // FIXME: in the SPM it would be nice to have system time instead of
1568         //        1394 time
1569         float rate = m_SyncSource->getTicksPerFrame();
1570
1571         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1572                 it != m_TransmitProcessors.end();
1573                 ++it ) {
1574             // this is the delay in frames between the point where a frame is received and
1575             // when it is transmitted again
1576             unsigned int one_ringbuffer_in_frames = m_nb_buffers * m_period + (*it)->getExtraBufferFrames();
1577             int64_t one_ringbuffer_in_ticks = (int64_t)(((float)one_ringbuffer_in_frames) * rate);
1578    
1579             // the data we are putting into the buffer is intended to be transmitted
1580             // one ringbuffer size after it has been received
1581             int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks);
1582
1583             if(!(*it)->putSilenceFrames(m_period, transmit_timestamp)) {
1584                 debugWarning("could not putSilenceFrames(%u,%" PRIu64 ") to stream processor (%p)\n",
1585                         m_period, transmit_timestamp, *it);
1586                 retval &= false; // buffer underrun
1587             }
1588         }
1589     }
1590     return retval;
1591 }
1592
1593 void StreamProcessorManager::dumpInfo() {
1594     debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n");
1595     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping StreamProcessorManager information...\n");
1596     debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %6d\n", m_nbperiods);
1597     debugOutputShort( DEBUG_LEVEL_NORMAL, "Data type: %s\n", (m_audio_datatype==eADT_Float?"float":"int24"));
1598
1599     debugOutputShort( DEBUG_LEVEL_NORMAL, " Receive processors...\n");
1600     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1601         it != m_ReceiveProcessors.end();
1602         ++it ) {
1603         (*it)->dumpInfo();
1604     }
1605
1606     debugOutputShort( DEBUG_LEVEL_NORMAL, " Transmit processors...\n");
1607     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1608         it != m_TransmitProcessors.end();
1609         ++it ) {
1610         (*it)->dumpInfo();
1611     }
1612
1613     debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n");
1614
1615     // list port info in verbose mode
1616     debugOutputShort( DEBUG_LEVEL_VERBOSE, "Port Information\n");
1617     int nb_ports;
1618    
1619     debugOutputShort( DEBUG_LEVEL_VERBOSE, " Playback\n");
1620     nb_ports = getPortCount(Port::E_Playback);
1621     for(int i=0; i < nb_ports; i++) {
1622         Port *p = getPortByIndex(i, Port::E_Playback);
1623         debugOutputShort( DEBUG_LEVEL_VERBOSE, "  %3d (%p): ", i, p);
1624         if (p) {
1625             bool disabled = p->isDisabled();
1626             debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%p] [%3s] ", &p->getManager(), (disabled?"off":"on"));
1627             debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%7s] ", p->getPortTypeName().c_str());
1628             debugOutputShort( DEBUG_LEVEL_VERBOSE, "%3s ", p->getName().c_str());
1629         } else {
1630             debugOutputShort( DEBUG_LEVEL_VERBOSE, "invalid ");
1631         }
1632         debugOutputShort( DEBUG_LEVEL_VERBOSE, "\n");
1633     }
1634     debugOutputShort( DEBUG_LEVEL_VERBOSE, " Capture\n");
1635     nb_ports = getPortCount(Port::E_Capture);
1636     for(int i=0; i < nb_ports; i++) {
1637         Port *p = getPortByIndex(i, Port::E_Capture);
1638         debugOutputShort( DEBUG_LEVEL_VERBOSE, "  %3d (%p): ", i, p);
1639         if (p) {
1640             bool disabled = p->isDisabled();
1641             debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%p] [%3s] ", &p->getManager(), (disabled?"off":"on"));
1642             debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%7s] ", p->getPortTypeName().c_str());
1643             debugOutputShort( DEBUG_LEVEL_VERBOSE, " %3s ", p->getName().c_str());
1644         } else {
1645             debugOutputShort( DEBUG_LEVEL_VERBOSE, " invalid ");
1646         }
1647         debugOutputShort( DEBUG_LEVEL_VERBOSE, "\n");
1648     }
1649
1650     debugOutputShort( DEBUG_LEVEL_VERBOSE, "----------------------------------------------------\n");
1651
1652 }
1653
1654 void StreamProcessorManager::setVerboseLevel(int l) {
1655     if(m_WaitLock) m_WaitLock->setVerboseLevel(l);
1656
1657     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1658         it != m_ReceiveProcessors.end();
1659         ++it ) {
1660         (*it)->setVerboseLevel(l);
1661     }
1662     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1663         it != m_TransmitProcessors.end();
1664         ++it ) {
1665         (*it)->setVerboseLevel(l);
1666     }
1667     setDebugLevel(l);
1668     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1669 }
1670
1671 int StreamProcessorManager::getPortCount(enum Port::E_PortType type, enum Port::E_Direction direction) {
1672     int count=0;
1673
1674     if (direction == Port::E_Capture) {
1675         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1676             it != m_ReceiveProcessors.end();
1677             ++it ) {
1678             count += (*it)->getPortCount(type);
1679         }
1680     } else {
1681         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1682             it != m_TransmitProcessors.end();
1683             ++it ) {
1684             count += (*it)->getPortCount(type);
1685         }
1686     }
1687     return count;
1688 }
1689
1690 int StreamProcessorManager::getPortCount(enum Port::E_Direction direction) {
1691     int count=0;
1692
1693     if (direction == Port::E_Capture) {
1694         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1695             it != m_ReceiveProcessors.end();
1696             ++it ) {
1697             count += (*it)->getPortCount();
1698         }
1699     } else {
1700         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1701             it != m_TransmitProcessors.end();
1702             ++it ) {
1703             count += (*it)->getPortCount();
1704         }
1705     }
1706     return count;
1707 }
1708
1709 void
1710 StreamProcessorManager::updateShadowLists()
1711 {
1712     debugOutput( DEBUG_LEVEL_VERBOSE, "Updating port shadow lists...\n");
1713     m_CapturePorts_shadow.clear();
1714     m_PlaybackPorts_shadow.clear();
1715
1716     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1717         it != m_ReceiveProcessors.end();
1718         ++it ) {
1719         PortManager *pm = *it;
1720         for (int i=0; i < pm->getPortCount(); i++) {
1721             Port *p = pm->getPortAtIdx(i);
1722             if (!p) {
1723                 debugError("getPortAtIdx(%d) returned NULL\n", i);
1724                 continue;
1725             }
1726             if(p->getDirection() != Port::E_Capture) {
1727                 debugError("port at idx %d for receive SP is not a capture port!\n", i);
1728                 continue;
1729             }
1730             m_CapturePorts_shadow.push_back(p);
1731         }
1732     }
1733     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1734         it != m_TransmitProcessors.end();
1735         ++it ) {
1736         PortManager *pm = *it;
1737         for (int i=0; i < pm->getPortCount(); i++) {
1738             Port *p = pm->getPortAtIdx(i);
1739             if (!p) {
1740                 debugError("getPortAtIdx(%d) returned NULL\n", i);
1741                 continue;
1742             }
1743             if(p->getDirection() != Port::E_Playback) {
1744                 debugError("port at idx %d for transmit SP is not a playback port!\n", i);
1745                 continue;
1746             }
1747             m_PlaybackPorts_shadow.push_back(p);
1748         }
1749     }
1750 }
1751
1752 Port* StreamProcessorManager::getPortByIndex(int idx, enum Port::E_Direction direction) {
1753     debugOutputExtreme( DEBUG_LEVEL_ULTRA_VERBOSE, "getPortByIndex(%d, %d)...\n", idx, direction);
1754     if (direction == Port::E_Capture) {
1755         #ifdef DEBUG
1756         if(idx >= (int)m_CapturePorts_shadow.size()) {
1757             debugError("Capture port %d out of range (%zd)\n", idx, m_CapturePorts_shadow.size());
1758             return NULL;
1759         }
1760         #endif
1761         return m_CapturePorts_shadow.at(idx);
1762     } else {
1763         #ifdef DEBUG
1764         if(idx >= (int)m_PlaybackPorts_shadow.size()) {
1765             debugError("Playback port %d out of range (%zd)\n", idx, m_PlaybackPorts_shadow.size());
1766             return NULL;
1767         }
1768         #endif
1769         return m_PlaybackPorts_shadow.at(idx);
1770     }
1771     return NULL;
1772 }
1773
1774 bool StreamProcessorManager::setThreadParameters(bool rt, int priority) {
1775     m_thread_realtime=rt;
1776     m_thread_priority=priority;
1777     return true;
1778 }
1779
1780
1781 } // end of namespace
Note: See TracBrowser for help on using the browser.