Changeset 491

Show
Ignore:
Timestamp:
07/11/07 17:33:30 (14 years ago)
Author:
jwoithe
Message:

More changes to restore MOTU functionality. We're getting closer but it's still not there yet.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libstreaming/MotuStreamProcessor.cpp

    r481 r491  
    6161  // iso buffering can delay the arrival of packets for quite a number of cycles 
    6262  // (have seen a delay >12 cycles). 
    63   if (abs(CYCLE_TIMER_GET_CYCLES(sph) - now_cycles) > 1000) { 
     63  // Every so often we also see sph wrapping ahead of ct_now, so deal with that 
     64  // too. 
     65  if (CYCLE_TIMER_GET_CYCLES(sph) > now_cycles + 1000) { 
    6466debugOutput(DEBUG_LEVEL_VERBOSE, "now=%d, ct=%d\n", now_cycles, CYCLE_TIMER_GET_CYCLES(sph)); 
    6567    if (ts_sec) 
     
    6769    else 
    6870      ts_sec = 127; 
     71  } else 
     72  if (now_cycles > CYCLE_TIMER_GET_CYCLES(sph) + 1000) { 
     73debugOutput(DEBUG_LEVEL_VERBOSE, "inverted wrap: now=%d, ct=%d\n", now_cycles, CYCLE_TIMER_GET_CYCLES(sph)); 
     74    if (ts_sec == 127) 
     75      ts_sec = 0; 
     76    else 
     77      ts_sec++; 
    6978  } 
    7079  return timestamp + ts_sec*TICKS_PER_SECOND; 
     
    7281 
    7382// Convert a full timestamp into an SPH timestamp as required by the MOTU 
    74 static inline uint32_t fullTicksToSph(uint32_t timestamp) { 
    75   return timestamp & 0x1ffffff; 
     83static inline uint32_t fullTicksToSph(int64_t timestamp) { 
     84  return TICKS_TO_CYCLE_TIMER(timestamp) & 0x1ffffff; 
    7685} 
    7786 
     
    119128    quadlet_t *quadlet = (quadlet_t *)data; 
    120129    signed int i; 
     130 
     131    // The number of events per packet expected by the MOTU is solely 
     132    // dependent on the current sample rate.  An 'event' is one sample from 
     133    // all channels plus possibly other midi and control data. 
     134    signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32); 
    121135 
    122136    m_last_cycle=cycle; 
     
    176190            // T1. 
    177191            ts_head = addTicks(ts_head, sync_lag_cycles * TICKS_PER_CYCLE); 
     192 
     193// These are just copied from AmdtpStreamProcessor.  At some point we should 
     194// verify that they make sense for the MOTU. 
     195            ts_head = substractTicks(ts_head, TICKS_PER_CYCLE); 
     196            // account for the number of cycles we are too late to enable 
     197            ts_head = addTicks(ts_head, cycles_past_enable * TICKS_PER_CYCLE); 
     198            // account for one extra packet of frames 
     199            ts_head = substractTicks(ts_head, 
     200              (uint32_t)((float)n_events * m_SyncSource->m_data_buffer->getRate()));  
    178201 
    179202            m_data_buffer->setBufferTailTimestamp(ts_head); 
     
    216239    int64_t timestamp = ts_head; 
    217240 
     241#if 0 
     242if (cycle<10000) { 
     243  debugOutput(DEBUG_LEVEL_VERBOSE,"cycle %d at %3d:%04d:%04d, timestamp=%3d:%04d:%04d (%d)\n", 
     244    cycle, 
     245    CYCLE_TIMER_GET_SECS(ctr), CYCLE_TIMER_GET_CYCLES(ctr), CYCLE_TIMER_GET_OFFSET(ctr), 
     246    TICKS_TO_SECS((uint32_t)timestamp), TICKS_TO_CYCLES((uint32_t)timestamp),TICKS_TO_OFFSET((uint32_t)timestamp),(uint32_t)timestamp); 
     247} 
     248#endif 
    218249    // we send a packet some cycles in advance, to avoid the 
    219250    // following situation: 
     
    238269    int32_t until_next=diffTicks(timestamp, cycle_timer + ticks_to_advance); 
    239270 
     271until_next = (cycle >= TICKS_TO_CYCLES((uint32_t)timestamp))?-1:1; 
     272 
    240273    // Size of a single data frame in quadlets 
    241274    unsigned dbs = m_event_size / 4; 
     
    277310    } 
    278311 
    279     // The number of events expected by the MOTU is solely dependent on 
    280     // the current sample rate.  An 'event' is one sample from all channels 
    281     // plus possibly other midi and control data. 
    282     signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32); 
    283  
    284312    // add the transmit transfer delay to construct the playout time 
    285313    uint64_t ts=addTicks(timestamp, TRANSMIT_TRANSFER_DELAY); 
     
    324352float ticks_per_frame = m_SyncSource->m_data_buffer->getRate(); 
    325353        for (i=0; i<n_events; i++, quadlet += dbs) { 
    326 //            unsigned int ts_frame = ts; 
    327             unsigned int ts_frame = timestamp
    328             ts_frame += (unsigned int)((float)i * ticks_per_frame); 
    329             *quadlet = htonl( TICKS_TO_CYCLE_TIMER(ts_frame) & 0x1ffffff); 
     354//FIXME: not sure which is best for the MOTU 
     355//            int64_t ts_frame = addTicks(ts, (unsigned int)(i * ticks_per_frame))
     356            int64_t ts_frame = addTicks(timestamp, (unsigned int)(i * ticks_per_frame)); 
     357            *quadlet = htonl(fullTicksToSph(ts_frame)); 
    330358#if 0 
    331 if (cycle==0) { 
    332   debugOutput(DEBUG_LEVEL_VERBOSE,"%d %d %d\n", 
     359if (i==0) { 
     360  debugOutput(DEBUG_LEVEL_VERBOSE,"  ts_frame=%8x (%3d:%04d:%04d)\n",ts_frame, 
     361    TICKS_TO_SECS(ts_frame), TICKS_TO_CYCLES(ts_frame), TICKS_TO_OFFSET(ts_frame)); 
     362
     363#endif 
     364#if 0 
     365if (cycle<2) { 
     366  debugOutput(DEBUG_LEVEL_VERBOSE,"cycle %d: %d %d %d\n", 
     367    cycle, 
    333368    TICKS_TO_SECS(ts_frame), 
    334369    TICKS_TO_CYCLES(ts_frame), 
     
    640675    // check if a wraparound on the secs will happen between 
    641676    // now and the time we start 
    642     if (CYCLE_TIMER_GET_CYCLES(now)>time_to_enable_at) { 
    643         // the start will happen in the next second 
     677    int until_enable=(int)time_to_enable_at - (int)CYCLE_TIMER_GET_CYCLES(now); 
     678 
     679    if(until_enable>4000) { 
     680        // wraparound on CYCLE_TIMER_GET_CYCLES(now) 
     681        // this means that we are late starting up, 
     682        // and that the start lies in the previous second 
     683        if (now_secs==0) now_secs=127; 
     684        else now_secs--; 
     685    } else if (until_enable<-4000) { 
     686        // wraparound on time_to_enable_at 
     687        // this means that we are early and that the start 
     688        // point lies in the next second 
    644689        now_secs++; 
    645690        if (now_secs>=128) now_secs=0; 
    646691    } 
    647692 
    648 //    uint64_t ts_head= now_secs*TICKS_PER_SECOND; 
    649     uint64_t ts_head = time_to_enable_at*TICKS_PER_CYCLE; 
     693////    uint64_t ts_head= now_secs*TICKS_PER_SECOND; 
     694//    uint64_t ts_head = time_to_enable_at*TICKS_PER_CYCLE; 
     695    uint64_t ts_head= now_secs*TICKS_PER_SECOND; 
     696    ts_head+=time_to_enable_at*TICKS_PER_CYCLE;  
    650697 
    651698    // we also add the nb of cycles we transmit in advance 
     
    689736 
    690737    // transfer the data 
     738#if 0 
     739debugOutput(DEBUG_LEVEL_VERBOSE, "1 - timestamp is %d\n", ts); 
     740#endif 
    691741    m_data_buffer->blockProcessWriteFrames(nbframes, ts); 
    692  
     742#if 0 
     743debugOutput(DEBUG_LEVEL_VERBOSE, "  done\n"); 
     744#endif 
    693745    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " New timestamp: %llu\n", ts); 
    694746 
     
    9771029    if (!m_disabled && m_is_disabled) { 
    9781030        // this means that we are trying to enable 
    979         if (cycle == m_cycle_to_enable_at) { 
     1031 
     1032        // check if we are on or past the enable point 
     1033        int cycles_past_enable=diffCycles(cycle, m_cycle_to_enable_at); 
     1034 
     1035        if (cycles_past_enable >= 0) { 
    9801036            m_is_disabled=false; 
    9811037            debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling Rx StreamProcessor %p at %d\n", 
     
    10431099// this packet, it perhaps makes more sense to acquire the timestamp of the last frame in the packet. 
    10441100// Then it's just a matter of adding m_ticks_per_frame rather than frame_size times this. 
     1101#if 0 
    10451102uint32_t first_sph = ntohl(*(quadlet_t *)(data+8)); 
    10461103//uint32_t first_sph = ntohl(*(quadlet_t *)(data+8+(event_length*(n_events-1)))); 
     
    10481105//        m_last_timestamp = CYCLE_TIMER_TO_TICKS(first_sph & 0x1ffffff); 
    10491106m_last_timestamp = sphRecvToFullTicks(first_sph, m_handler->getCycleTimer()); 
    1050  
     1107float frame_size=m_framerate<=48000?8:(m_framerate<=96000?16:32); 
     1108uint64_t ts=addTicks(m_last_timestamp, (uint64_t)((frame_size-1) * m_ticks_per_frame)); 
     1109m_last_timestamp = ts; 
     1110#endif 
     1111 
     1112#if 1 
     1113uint32_t last_sph = ntohl(*(quadlet_t *)(data+8+(n_events-1)*event_length)); 
     1114m_last_timestamp = sphRecvToFullTicks(last_sph, m_handler->getCycleTimer()); 
     1115#endif 
     1116                                                          
    10511117        // Signal that we're running 
    10521118        if(!m_running && n_events && m_last_timestamp2 && m_last_timestamp) { 
     
    10721138 
    10731139            // set the timestamp as if there will be a sample put into 
    1074             // the buffer by the next packet. 
     1140            // the buffer by the next packet.  This means we use the timestamp 
     1141            // corresponding to the last frame which would have been added to the 
     1142            // buffer this cycle if we weren't disabled. 
    10751143if (ts >= 128L* TICKS_PER_SECOND) 
    10761144  ts -= 128L*TICKS_PER_SECOND; 
    1077             m_data_buffer->setBufferTailTimestamp(ts); 
     1145//            m_data_buffer->setBufferTailTimestamp(ts); 
     1146            m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 
    10781147//debugOutput(DEBUG_LEVEL_VERBOSE,"%p, last ts=%lld, ts=%lld, lts2=%lld\n", m_data_buffer, m_last_timestamp, ts, m_last_timestamp2); 
    10791148 
     
    10821151 
    10831152        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n"); 
    1084 //debugOutput(DEBUG_LEVEL_VERBOSE,"enabled: %p, last ts=%lld, ts2=%lld\n",m_data_buffer, m_last_timestamp, m_last_timestamp2); 
     1153//debugOutput(DEBUG_LEVEL_VERBOSE,"cycle=%d, mp=%d, last ts=%lld, ts2=%lld\n",cycle,m_period, m_last_timestamp, m_last_timestamp2); 
    10851154 
    10861155        //=> process the packet 
    10871156        // add the data payload to the ringbuffer 
     1157        // Note: the last argument to writeFrames is the timestamp of the *last sample* being 
     1158        // added. 
    10881159        if(m_data_buffer->writeFrames(n_events, (char *)(data+8), m_last_timestamp)) { 
    10891160            retval=RAW1394_ISO_OK; 
    1090  
    10911161            int dbc = get_bits(ntohl(quadlet[0]), 8, 8); 
    10921162