Changeset 300

Show
Ignore:
Timestamp:
09/04/06 17:10:19 (16 years ago)
Author:
jwoithe
Message:

Major cleanup of MOTU streaming code.
Fine-tuned the DLL used for iso transmission timestamping.
Tweaked MOTU shutdown to avoid long delays if streaming isn't operational; this means that xrun recovery nearly always works now.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.cpp

    r296 r300  
    4242IMPL_DEBUG_MODULE( MotuReceiveStreamProcessor, MotuReceiveStreamProcessor, DEBUG_LEVEL_NORMAL ); 
    4343 
     44// Set to 1 to enable the generation of a 1 kHz test tone in analog output 1 
     45#define TESTTONE 1 
     46 
    4447// A macro to extract specific bits from a native endian quadlet 
    4548#define get_bits(_d,_start,_len) (((_d)>>((_start)-(_len)+1)) & ((1<<(_len))-1)) 
     
    4952                unsigned int event_size) 
    5053        : TransmitStreamProcessor(port, framerate), m_event_size(event_size), 
    51         m_tx_dbc(0), m_cycle_count(-1), m_cycle_ofs(0.0), m_ticks_per_frame(NULL), 
    52         m_closedown_count(-1) { 
    53  
     54        m_tx_dbc(0), m_cycle_count(-1), m_cycle_ofs(0.0), m_next_cycle(-1),  
     55        m_ticks_per_frame(NULL), m_closedown_count(-1), m_streaming_active(0) { 
    5456} 
    5557 
     
    6971                return false; 
    7072        } 
     73        m_next_cycle = -1; 
    7174        m_closedown_count = -1; 
     75        m_streaming_active = 0; 
     76        m_cycle_count = -1; 
     77        m_cycle_ofs = 0.0; 
    7278 
    7379        return true; 
     
    8995#define CYCLE_DELAY 1 
    9096 
    91 // FIXME: every so often sync seems to be missed on startup, and because 
    92 // this code can't recover a sync the problem remains indefinitely.  The 
    93 // cause of this needs to be identified.  It may be the result of not 
    94 // running with RT privileges for this initial testing phase.  Even so, sync 
    95 // recovery needs to be implemented. 
    96  
    9797        enum raw1394_iso_disposition retval = RAW1394_ISO_OK; 
    9898        quadlet_t *quadlet = (quadlet_t *)data; 
    9999        signed int i; 
    100  
    101 signed int corrected_cycle = cycle; 
     100        signed int unwrapped_cycle = cycle; 
     101 
     102        // Signal that streaming is still active 
     103        m_streaming_active = 1; 
    102104 
    103105        // The MOTU transmit stream is 'always' ready 
     
    126128        signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32); 
    127129 
    128 // FIXME: some tests - attempt to recover sync after loss due to missed cycles 
    129 static signed int next_cycle = -1; 
    130 //static suseconds_t us_stack[10] = {0,0,0,0,0,0,0,0,0,0}; 
    131 //static int us_i = 0; 
    132 //struct timeval tv; 
    133 //gettimeofday(&tv, NULL); 
    134 //us_stack[us_i] = tv.tv_usec + (tv.tv_sec%10)*1000000; 
    135 //if (++us_i == 10) 
    136 //  us_i = 0; 
    137  
    138 if (!m_disabled && next_cycle>=0 && cycle!=next_cycle) { 
    139   debugOutput(DEBUG_LEVEL_VERBOSE, "tx cycle miss: %d requested, %d expected\n",cycle,next_cycle); 
    140   debugOutput(DEBUG_LEVEL_VERBOSE, "tx stream: cycle=%d, ofs=%g\n",m_cycle_count, m_cycle_ofs); 
    141  
    142 // Print the times of the last 10 calls to this function 
    143 //int i = us_i, l = -1; 
    144 //  fprintf(stderr,"usec stack:\n"); 
    145 //  do { 
    146 //    fprintf(stderr, "  %d",us_stack[i]); 
    147 //    if (l != -1)  
    148 //      fprintf(stderr," (%d)",us_stack[i]-us_stack[l]); 
    149 //    l = i; 
    150 //    if (++i == 10)  
    151 //      i = 0; 
    152 //  } while (i != us_i); 
    153 //  fprintf(stderr,"\n"); 
    154  
    155 #if 0 
    156 // This "simple" way out doesn't work, probably because there's no 
    157 // guarantee that ofs 0 in the current cycle is anywhere near an audio 
    158 // sample point. 
    159 m_cycle_count = cycle; 
    160 m_cycle_ofs = 0.0; 
    161 m_tx_dbc = 0; 
    162 #else 
    163 float ftmp; 
    164 signed int ccount; 
    165  
    166   ccount = next_cycle; 
    167   while (ccount!=cycle) { 
    168  
    169 corrected_cycle = ccount; 
    170 if (m_cycle_count-ccount > 7900) 
    171   corrected_cycle += 8000; 
    172  
    173     if (corrected_cycle < m_cycle_count) { 
    174       if (++ccount == 8000) 
    175         ccount = 0; 
    176       continue; 
    177     } 
    178     m_tx_dbc += n_events; 
    179     incrementFrameCounter(n_events); 
    180  
    181     ftmp = m_cycle_ofs+n_events*(*m_ticks_per_frame); 
    182     m_cycle_count += (unsigned int)ftmp/3072; 
    183     m_cycle_count %= 8000; 
    184     m_cycle_ofs = fmod(ftmp, 3072); 
    185  
    186     if (++ccount == 8000) 
    187       ccount = 0; 
    188   } 
    189   m_tx_dbc &= 0xff; 
    190  
    191 #endif 
    192   debugOutput(DEBUG_LEVEL_VERBOSE, "  resuming with cyclecount=%d, cycleofs=%g (ticksperfame=%g)\n", 
    193     m_cycle_count, m_cycle_ofs, *m_ticks_per_frame); 
    194 
    195 if (!m_disabled) 
    196   next_cycle = (cycle+1)%8000; 
    197 else 
    198   next_cycle = -1; 
     130        // Size of data to read from the event buffer, in bytes. 
     131        unsigned int read_size = n_events * m_event_size; 
     132 
     133        // Detect a missed cycle and attempt to "catch up". 
     134        if (!m_disabled && m_next_cycle>=0 && cycle!=m_next_cycle) { 
     135                float ftmp; 
     136                signed int ccount = m_next_cycle; 
     137                debugOutput(DEBUG_LEVEL_VERBOSE, "tx cycle miss: %d requested, %d expected\n",cycle,m_next_cycle); 
     138 
     139                while (ccount!=cycle) { 
     140                        unwrapped_cycle = ccount; 
     141                        if (m_cycle_count-ccount > 7900) 
     142                                unwrapped_cycle += 8000; 
     143 
     144                        if (unwrapped_cycle < m_cycle_count) { 
     145                                if (++ccount == 8000) 
     146                                        ccount = 0; 
     147                                continue; 
     148                        } 
     149                        // Advance buffers and counters as if this cycle had been dealt with 
     150                        m_tx_dbc += n_events; 
     151                        incrementFrameCounter(n_events); 
     152 
     153                        ftmp = m_cycle_ofs+n_events*(*m_ticks_per_frame); 
     154                        m_cycle_count += (unsigned int)ftmp/3072; 
     155                        m_cycle_count %= 8000; 
     156                        m_cycle_ofs = fmod(ftmp, 3072); 
     157 
     158                        if (++ccount == 8000) 
     159                                ccount = 0; 
     160 
     161                        // Also advance the event buffer to keep things in sync 
     162                        freebob_ringbuffer_read_advance(m_event_buffer,read_size); 
     163                } 
     164                m_tx_dbc &= 0xff; 
     165                debugOutput(DEBUG_LEVEL_VERBOSE, "  resuming with cyclecount=%d, cycleofs=%g (ticksperfame=%g)\n", 
     166                        m_cycle_count, m_cycle_ofs, *m_ticks_per_frame); 
     167 
     168                m_next_cycle = cycle; 
     169        } 
     170 
     171 
     172        if (!m_disabled) { 
     173                if (++m_next_cycle >= 8000) 
     174                        m_next_cycle -= 8000; 
     175        } else 
     176                m_next_cycle = -1; 
    199177 
    200178        // Deal cleanly with potential wrap-around cycle counter conditions 
    201         corrected_cycle = cycle; 
     179        unwrapped_cycle = cycle; 
    202180        if (m_cycle_count-cycle > 7900) 
    203                 corrected_cycle += 8000; 
     181                unwrapped_cycle += 8000; 
    204182 
    205183        // Increment the dbc (data block count).  This is only done if the 
     
    209187        // first packet containing data will have a DBC of n_events, which 
    210188        // matches what is observed from other systems. 
    211         if (!m_disabled && corrected_cycle>=m_cycle_count) { 
     189        if (!m_disabled && unwrapped_cycle>=m_cycle_count) { 
    212190                m_tx_dbc += n_events; 
    213191                if (m_tx_dbc > 0xff) 
     
    228206        // ahead of the ieee1394 cycle timer, we send a data-less packet 
    229207        // with only the 8 byte CIP-like header set up previously. 
    230         if (m_disabled || corrected_cycle<m_cycle_count) { 
     208        if (m_disabled || unwrapped_cycle<m_cycle_count) { 
    231209                return RAW1394_ISO_OK; 
    232210        } 
    233  
    234         // Size of data to read from the event buffer, in bytes. 
    235         unsigned int read_size = n_events * m_event_size; 
    236211 
    237212        // In the disabled state simply zero all data sent to the MOTU.  If 
     
    282257                // Set up each frames's SPH.  Note that the (int) typecast 
    283258                // appears to do rounding. 
    284                 // FIXME: once working, make more efficient by removing 1 of the 
    285                 // "trim to 8000" operations. 
     259                // 
     260                // CYCLE_DELAY accounts for the delay between the cycle 
     261                // audio is sent in and when the MOTU can actually play  
     262                // that audio.  The SPH timestamp must account for this 
     263                // it doesn't demand to be played before it's possible. 
     264                // For the duration of the event loop, account for the 
     265                // CYCLE_DELAY within m_cycle_count to save having to wrap 
     266                // (m_cycle_count+CYCLE_DELAY) and m_cycle_count separately 
     267                // within the event loop.  Once the loop is finished we 
     268                // reset m_cyle_count to once again refer to the send 
     269                // cycle rather than the audio presentation cycle. 
     270                // 
     271                // This seemingly messy treatment saves one modulo operation 
     272                // per loop iteration.  Since the loop count ranges from 8 
     273                // (for 1x sample rates) to 32 there are considerable 
     274                // savings to be made even at 1x rates. 
     275                if ((m_cycle_count+=CYCLE_DELAY) >= 8000) 
     276                        m_cycle_count -= 8000; 
    286277                for (i=0; i<n_events; i++, quadlet += dbs) { 
    287                         *quadlet = htonl( (((m_cycle_count+CYCLE_DELAY)%8000)<<12) +  
    288                                         (int)m_cycle_ofs); 
    289 // FIXME: remove this hacked in 1 kHz test signal to analog-1 when testing 
    290 // is complete.  Note that the tone is *not* added during closedown. 
    291 if (m_closedown_count<0) { 
    292 //static signed int a_cx=0, a_ofs=0; 
    293 static signed int a_cx = 0; 
    294 signed int val; 
    295 // val = (int)(0x7fffff*sin(1000.0*2.0*M_PI*(m_cycle_count+((m_cycle_ofs)/3072.0))/8000.0)); 
    296 val = (int)(0x7fffff*sin(1000.0*2.0*M_PI*(a_cx/24576000.0))); 
    297 if ((a_cx+=512) >= 24576000) { 
    298   a_cx -= 24576000; 
    299 
    300 //val = (int)(0x7fffff*sin(1000.0*2.0*M_PI*(a_cx+(float(a_ofs)/3072.0))/8000.0)); 
    301 //if ((a_ofs+=512) >= 3072) { 
    302 //  a_ofs -= 3072; 
    303 //  if (++a_cx > 7999) 
    304 //    a_cx -= 8000; 
    305 //} 
    306 *(data+8+i*m_event_size+16) = (val >> 16) & 0xff; 
    307 *(data+8+i*m_event_size+17) = (val >> 8) & 0xff; 
    308 *(data+8+i*m_event_size+18) = val & 0xff; 
    309 
    310                         m_cycle_ofs += *m_ticks_per_frame; 
    311                         if (m_cycle_ofs >= 3072) { 
     278                        *quadlet = htonl( (m_cycle_count<<12) + (int)m_cycle_ofs); 
     279#if TESTTONE 
     280                        // FIXME: remove this hacked in 1 kHz test signal to 
     281                        // analog-1 when testing is complete.  Note that the tone is 
     282                        // *never* added during closedown. 
     283                        if (m_closedown_count<0) { 
     284                                static signed int a_cx = 0; 
     285                                signed int val; 
     286                                val = (int)(0x7fffff*sin(1000.0*2.0*M_PI*(a_cx/24576000.0))); 
     287                                if ((a_cx+=512) >= 24576000) { 
     288                                        a_cx -= 24576000; 
     289                                } 
     290                                *(data+8+i*m_event_size+16) = (val >> 16) & 0xff; 
     291                                *(data+8+i*m_event_size+17) = (val >> 8) & 0xff; 
     292                                *(data+8+i*m_event_size+18) = val & 0xff; 
     293                        } 
     294#endif 
     295                        if ((m_cycle_ofs+=*m_ticks_per_frame) >= 3072) { 
    312296                                m_cycle_ofs -= 3072; 
    313297                                if (++m_cycle_count > 7999) 
     
    315299                        } 
    316300                } 
     301                // Reset m_cycle_count to the send cycle 
     302                if ((m_cycle_count-=CYCLE_DELAY) < 0) 
     303                        m_cycle_count += 8000; 
    317304 
    318305                // Process all ports that should be handled on a per-packet base 
     
    394381                return false;     
    395382        } 
     383 
     384        m_next_cycle = -1; 
     385        m_closedown_count = -1; 
     386        m_streaming_active = 0; 
     387        m_cycle_count = -1; 
     388        m_cycle_ofs = 0.0; 
    396389 
    397390        return true; 
     
    728721} 
    729722 
    730 /* Left in as reference, this is highly AMDTP related 
    731  
    732 basic idea: 
    733  
    734 iterate over the ports 
    735 - get port buffer address 
    736 - loop over events 
    737   * pick right sample in event based upon PortInfo 
    738   * convert sample from Port format (E_Int24, E_Float, ..) to native format 
    739  
    740 not that in order to use the 'efficient' transfer method, you have to make sure that 
    741 you can start from an offset (expressed in frames). 
    742 */ 
    743 #include <math.h> 
    744  
    745723int MotuTransmitStreamProcessor::encodePortToMBLAEvents(MotuAudioPort *p, quadlet_t *data,  
    746724                       unsigned int offset, unsigned int nevents) { 
     725// Encodes nevents worth of data from the given port into the given buffer.  The 
     726// format of the buffer is precisely that which will be sent to the MOTU. 
     727// The basic idea: 
     728//   iterate over the ports 
     729//     * get port buffer address 
     730//     * loop over events 
     731//         - pick right sample in event based upon PortInfo 
     732//         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU 
     733//           native format 
     734// 
     735// We include the ability to start the transfer from the given offset within 
     736// the port (expressed in frames) so the 'efficient' transfer method can be 
     737// utilised. 
     738 
    747739        unsigned int j=0; 
    748740 
     
    825817bool MotuTransmitStreamProcessor::preparedForStop() { 
    826818 
    827         // FIXME: ideally we want to include a condition which tests if the 
    828         // stream shutdown is in response to an xrun due to a problem at 
    829         // startup, and unconditionally return true.  This saves a few 
    830         // seconds delay since under these conditions the iso transmit 
    831         // callback doesn't appear to be called and therefore 
    832         // m_closedown_count is never decremented.  We can't just test for 
    833         // an xrun however since sometimes these can occur "normally" during 
    834         // shutdown.  This is probably all tied up with the sync recovery 
    835         // issue which hasn't really been explored yet. 
    836         if (m_disabled || !isRunning()) 
     819        // If the stream is disabled or isn't running there's no need to 
     820        // wait since the MOTU *should* still be in a "zero data" state. 
     821        // 
     822        // If the m_streaming_active flag is 0 it indicates that the 
     823        // transmit callback hasn't been called since a closedown was 
     824        // requested when this function was last called.  This effectively 
     825        // signifies that the streaming thread has been exitted due to an 
     826        // xrun in either the receive or transmit handlers.  In this case 
     827        // there's no point in waiting for the closedown count to hit zero 
     828        // because it never will; the zero data will never get to the MOTU.  
     829        // It's best to allow an immediate stop and let the xrun handler 
     830        // proceed as best it can. 
     831        // 
     832        // The ability to detect the lack of streaming also prevents the 
     833        // "wait for stop" in the stream processor manager's stop() method 
     834        // from hitting its timeout which in turn seems to increase the 
     835        // probability of a successful recovery. 
     836        if (m_disabled || !isRunning() || !m_streaming_active) 
    837837                return true; 
    838838 
     
    850850                signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32); 
    851851                m_closedown_count = m_period / n_events; 
     852 
     853                // Set up a test to confirm that streaming is still active. 
     854                // If the streaming function hasn't been called by the next 
     855                // iteration through this function there's no point in 
     856                // continuing since it means the zero data will never get to  
     857                // the MOTU. 
     858                m_streaming_active = 0; 
    852859                return false; 
    853860        } 
     
    864871        unsigned int event_size) 
    865872    : ReceiveStreamProcessor(port, framerate), m_event_size(event_size), 
    866         m_last_cycle_ofs(-1)
     873        m_last_cycle_ofs(-1), m_next_cycle(-1)
    867874 
    868875        // Set up the Delay-locked-loop to track audio frequency relative 
    869         // to the cycle timer.  The seed value is just the difference one 
    870         // would see if the audio clock was locked to the ieee1394 cycle 
    871         // timer. 
     876        // to the cycle timer.  The seed value is the "ideal" value. 
    872877        m_ticks_per_frame = 24576000.0/framerate; 
    873878} 
     
    897902     
    898903    enum raw1394_iso_disposition retval=RAW1394_ISO_OK; 
    899  
    900 // FIXME: just for debugging, print out the sph ofs DLL value 
    901 // once a second 
    902 //if (cycle==0) { 
    903 //  fprintf(stderr, "m_ticks_per_frame=%g\n",*m_ticks_per_frame); 
    904 //} 
    905  
    906 // FIXME: more debugging 
    907 static signed int last_cycle=-1; 
    908 if (last_cycle>=0 && (signed)cycle!=(last_cycle+1)%8000) { 
    909   debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n", 
    910     cycle, (last_cycle+1)%8000); 
    911 
    912 last_cycle=cycle; 
     904    signed int have_lost_cycles = 0; 
     905 
     906    // Detect missed receive cycles 
     907    // FIXME: it would be nice to advance the rx buffer by the amount of 
     908    // frames missed.  However, since the MOTU transmits more frames  
     909    // per cycle than the average and "catches up" with period emty 
     910    // cycles it's not trivial to work out precisely how many frames 
     911    // were missed.  Ultimately we need to do so if sync is to be  
     912    // maintained across a transient receive failure. 
     913    if (m_next_cycle < 0) 
     914        m_next_cycle = cycle; 
     915    if ((signed)cycle != m_next_cycle) { 
     916        debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n", 
     917            cycle, m_next_cycle); 
     918        m_next_cycle = cycle; 
     919        have_lost_cycles = 1; 
     920    } 
     921    if (++m_next_cycle >= 8000) 
     922        m_next_cycle -= 8000; 
    913923 
    914924    // If the packet length is 8 bytes (ie: just a CIP-like header) there is 
     
    933943        if (n_events) m_running=true; 
    934944 
    935 #if 1 
    936         /* FIXME: test whether things are improved by doing this in the 
    937          * actual receive handler.  The advantage is that we don't have to 
    938          * wait until the stream is enabled before the DLL starts tracking.  
    939          * This has the desireable side-effect of having a relatively 
    940          * accurate value in the DLL by the time the transmit stream is 
    941          * enabled.  A disadvantage of having this in here is that it 
    942          * increases the time spent in this function.  Whether this is 
    943          * important in practice remains to be seen.  Ad hoc evidence thus 
    944          * far seems to suggest that it does increase the chances of a 
    945          * faulty startup, but more tests are needed. 
    946          */ 
    947         /* Push cycle offset differences from each event's SPH into the DLL. 
    948          * If this is the very first block received, use the first event to 
    949          * initialise the last cycle offset. 
    950          * FIXME: it might be best to use differences only within the given 
    951          * block rather than keeping a store of the last cycle offset. 
    952          * Otherwise in the event of a lost incoming packet the DLL will 
    953          * have an abnormally large value sent to it.  Perhaps this doesn't 
    954          * matter? 
     945        /* Send actual ticks-per-frame values (as deduced by the incoming  
     946         * SPHs) to the DLL for averaging.  Doing this here means the DLL 
     947         * should acquire a reasonable estimation of the ticks per frame 
     948         * even while the stream is formally disabled.  This in turn means 
     949         * the transmit stream should have access to a very realistic  
     950         * estimate by the time it is enabled.  The major disadvantage 
     951         * is a small increase in the overheads of this function compared 
     952         * to what would be the case if this was delayed by pushing it into 
     953         * the decode functions. 
    955954         */ 
    956955        unsigned int ev; 
    957         signed int sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff; 
    958  
    959 //      if (m_last_cycle_ofs < 0) { 
    960 //              m_last_cycle_ofs = sph_ofs-(int)(*m_ticks_per_frame); 
    961 //      } 
    962         m_last_cycle_ofs = sph_ofs; 
    963         for (ev=1; ev<n_events; ev++) { 
     956        signed int sph_ofs; 
     957 
     958        /* If this is the first block received or we have lost cycles, 
     959         * initialise the m_last_cycle_ofs to a value which won't cause the 
     960         * DLL to become polluted with an inappropriate ticks-per-frame 
     961         * estimate. 
     962         */ 
     963        if (m_last_cycle_ofs<0 || have_lost_cycles) { 
     964                sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff; 
     965                m_last_cycle_ofs = sph_ofs-(int)(m_ticks_per_frame); 
     966        } 
     967        for (ev=0; ev<n_events; ev++) { 
    964968                sph_ofs = ntohl(*(quadlet_t *)(data+8+ev*m_event_size)) & 0xfff; 
    965                 signed int sph_diff = (m_last_cycle_ofs<sph_ofs)? 
    966                         sph_ofs-m_last_cycle_ofs:sph_ofs+3072-m_last_cycle_ofs; 
     969                signed int sph_diff = (sph_ofs - m_last_cycle_ofs); 
     970                // Handle wraparound of the cycle offset 
     971                if (sph_diff < 0) 
     972                        sph_diff += 3072; 
    967973                float err = sph_diff - m_ticks_per_frame; 
    968974                // FIXME: originally we used a value of 0.0005 for the coefficient 
     
    971977                // However, tests showed that this introduced discontinuities in 
    972978                // the output audio signal, so an alternative value was sought. 
    973                 // Further tests are needed, but a value of 0.01 seems to work 
     979                // Further tests are needed, but a value of 0.015 seems to work 
    974980                // well, at least at a sample rate of 48 kHz. 
    975                 m_ticks_per_frame += 0.01*err; 
    976  
     981                m_ticks_per_frame += 0.015*err; 
    977982                m_last_cycle_ofs = sph_ofs; 
    978983        } 
    979 #endif 
    980  
    981  
    982984 
    983985        // Don't process the stream when it is not enabled. 
     
    12071209                * the remaining nb of bytes in one read operation can be smaller than one event 
    12081210                * this can happen because the ringbuffer size is always a power of 2 
    1209                        */ 
     1211                */ 
    12101212                if(vec[0].len<m_event_size) { 
    12111213                        // use the ringbuffer function to read one event  
     
    12591261{ 
    12601262        int problem=0; 
    1261 #if 0 
    1262         /* Push cycle offset differences from each event's SPH into the DLL. 
    1263          * If this is the very first block received, use the first event to 
    1264          * initialise the last cycle offset. 
    1265          * FIXME: it might be best to use differences only within the given 
    1266          * block rather than keeping a store of the last cycle offset. 
    1267          * Otherwise in the event of a lost incoming packet the DLL will 
    1268          * have an abnormally large value sent to it.  Perhaps this doesn't 
    1269          * matter? 
    1270          */ 
    1271         unsigned int ev; 
    1272         signed int sph_ofs = ntohl(*(quadlet_t *)data) & 0xfff; 
    1273  
    1274         if (m_last_cycle_ofs < 0) { 
    1275 //              m_last_cycle_ofs = sph_ofs-(int)(*m_ticks_per_frame); 
    1276                 m_last_cycle_ofs = sph_ofs - m_ticks_per_frame; 
    1277         } 
    1278         for (ev=0; ev<nevents; ev++) { 
    1279                 sph_ofs = ntohl(*(quadlet_t *)(data+ev*m_event_size)) & 0xfff; 
    1280                 signed int sph_diff = (m_last_cycle_ofs<sph_ofs)? 
    1281                         sph_ofs-m_last_cycle_ofs:sph_ofs+3072-m_last_cycle_ofs; 
    1282                 float err = sph_diff - m_ticks_per_frame; 
    1283                 // FIXME: originally we used a value of 0.0005 for the coefficient 
    1284                 // which mirrored the value used in 
    1285                 // AmdtpReceiveStreamProcessor::putPacket() for a similar purpose. 
    1286                 // However, tests showed that this introduced discontinuities in 
    1287                 // the output audio signal, so an alternative value was sought. 
    1288                 // Further tests are needed, but a value of 0.01 seems to work 
    1289                 // well, at least at a sample rate of 48 kHz. 
    1290                 m_ticks_per_frame += 0.01*err; 
    1291  
    1292                 m_last_cycle_ofs = sph_ofs; 
    1293         } 
    1294 #endif 
    12951263        for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    12961264          it != m_PeriodPorts.end(); 
  • branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.h

    r296 r300  
    88 * 
    99 *   Copyright (C) 2005,2006 Pieter Palmers <pieterpalmers@users.sourceforge.net> 
     10 *   Copyright (C) 2006 Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 
    1011 * 
    1112 *   This program is free software {} you can redistribute it and/or modify 
     
    9495        float m_cycle_ofs; 
    9596 
     97        // Used to detect missed cycles 
     98        signed int m_next_cycle; 
     99 
    96100        // Hook to the DLL in the receive stream which provides a 
    97101        // continuously updated estimate of the number of ieee1394 ticks 
     
    101105        // Used to keep track of the close-down zeroing of output data 
    102106        signed int m_closedown_count; 
     107        signed int m_streaming_active; 
    103108 
    104109    bool prefill(); 
     
    183188 
    184189        signed int m_last_cycle_ofs; 
     190        signed int m_next_cycle; 
    185191 
    186192    DECLARE_DEBUG_MODULE; 
  • branches/libfreebob-2.0/src/motu/motu_avdevice.h

    r290 r300  
    11/* motu_avdevice.h 
    22 * Copyright (C) 2006 by Pieter Palmers 
     3 * Copyright (C) 2006 Jonathan Woithe 
    34 * 
    45 * This file is part of FreeBob.