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

Revision 2651, 70.6 kB (checked in by jwoithe, 7 years ago)

Fix some warnings emitted by recent versions of gcc. These are mostly connected with printf format strings: spaces are now required between string literals and PR* format macros. Patch from Xavier Forestier.

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 aquired 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.