Changeset 360
- Timestamp:
- 12/30/06 11:49:46 (17 years ago)
- Files:
-
- trunk/libfreebob/config.h.in (modified) (1 diff)
- trunk/libfreebob/src/bebob/bebob_avdevice.cpp (modified) (1 diff)
- trunk/libfreebob/src/debugmodule/debugmodule.cpp (modified) (2 diffs)
- trunk/libfreebob/src/libstreaming/AmdtpStreamProcessor.cpp (modified) (28 diffs)
- trunk/libfreebob/src/libstreaming/AmdtpStreamProcessor.h (modified) (3 diffs)
- trunk/libfreebob/src/libstreaming/freebob_streaming.cpp (modified) (7 diffs)
- trunk/libfreebob/src/libstreaming/IsoHandler.cpp (modified) (11 diffs)
- trunk/libfreebob/src/libstreaming/IsoHandler.h (modified) (10 diffs)
- trunk/libfreebob/src/libstreaming/IsoHandlerManager.cpp (modified) (3 diffs)
- trunk/libfreebob/src/libstreaming/IsoHandlerManager.h (modified) (3 diffs)
- trunk/libfreebob/src/libstreaming/StreamProcessorManager.cpp (modified) (3 diffs)
- trunk/libfreebob/src/libutil/cycles.h (added)
- trunk/libfreebob/src/libutil/SystemTimeSource.cpp (added)
- trunk/libfreebob/src/libutil/SystemTimeSource.h (added)
- trunk/libfreebob/src/libutil/Time.c (added)
- trunk/libfreebob/src/libutil/Time.h (added)
- trunk/libfreebob/src/libutil/TimeSource.cpp (added)
- trunk/libfreebob/src/libutil/TimeSource.h (added)
- trunk/libfreebob/src/Makefile.am (modified) (5 diffs)
- trunk/libfreebob/support/jack/freebob_driver.c (modified) (2 diffs)
- trunk/libfreebob/tests/Makefile.am (modified) (3 diffs)
- trunk/libfreebob/tests/streaming/test-isohandling.cpp (modified) (1 diff)
- trunk/libfreebob/tests/SytMonitor.cpp (added)
- trunk/libfreebob/tests/SytMonitor.h (added)
- trunk/libfreebob/tests/test-cyclecounter.cpp (added)
- trunk/libfreebob/tests/test-sytmonitor.cpp (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libfreebob/config.h.in
r358 r360 84 84 #undef const 85 85 86 /* Define to `unsigned int' if <sys/types.h> does not define. */86 /* Define to `unsigned' if <sys/types.h> does not define. */ 87 87 #undef size_t 88 88 trunk/libfreebob/src/bebob/bebob_avdevice.cpp
r336 r360 110 110 {0x000a92, 0x00010066}, // Presonous FirePOD 111 111 112 {0x000aac, 0x00000003}, // TerraTec Electronic GmbH, Phase 88 FW 112 113 {0x000aac, 0x00000004}, // TerraTec Electronic GmbH, Phase X24 FW (model version 4) 113 114 {0x000aac, 0x00000007}, // TerraTec Electronic GmbH, Phase X24 FW (model version 7) trunk/libfreebob/src/debugmodule/debugmodule.cpp
r336 r360 54 54 DebugModule::~DebugModule() 55 55 { 56 cerr << "Unregistering " 57 << this->getName() 58 << " at DebugModuleManager" 59 << endl; 56 60 if ( !DebugModuleManager::instance()->unregisterModule( *this ) ) { 57 61 cerr << "Could not unregister DebugModule at DebugModuleManager" … … 139 143 ++it ) 140 144 { 141 fprintf(stderr,"Cleaning up leftover debug module: %s ",(*it)->getName().c_str());145 fprintf(stderr,"Cleaning up leftover debug module: %s\n",(*it)->getName().c_str()); 142 146 m_debugModules.erase( it ); 143 147 delete *it; trunk/libfreebob/src/libstreaming/AmdtpStreamProcessor.cpp
r268 r360 31 31 #include "AmdtpPort.h" 32 32 33 #include "cyclecounter.h" 34 33 35 #include <netinet/in.h> 34 36 #include <assert.h> 35 37 36 #define CYCLE_COUNTER_GET_SECS(x) (((x & 0xFE000000) >> 25)) 37 #define CYCLE_COUNTER_GET_CYCLES(x) (((x & 0x01FFF000) >> 12)) 38 #define CYCLE_COUNTER_GET_TICKS(x) (((x & 0x00000FFF))) 39 #define CYCLE_COUNTER_TO_TICKS(x) ((CYCLE_COUNTER_GET_SECS(x) * 24576000) +\ 40 (CYCLE_COUNTER_GET_CYCLES(x) * 3072) +\ 41 (CYCLE_COUNTER_GET_TICKS(x) )) 42 43 // this is one milisecond of processing delay 44 #define TICKS_PER_SECOND 24576000 38 #define RECEIVE_PROCESSING_DELAY_IN_SAMPLES 100 39 #define RECEIVE_DLL_INTEGRATION_COEFFICIENT 0.015 40 45 41 #define RECEIVE_PROCESSING_DELAY (TICKS_PER_SECOND * 2/1000) 46 #define TRANSMIT_PROCESSING_DELAY RECEIVE_PROCESSING_DELAY 42 43 // in ticks 44 #define TRANSMIT_TRANSFER_DELAY 10000 45 46 //#define DO_SYT_SYNC 47 47 48 48 namespace FreebobStreaming { … … 54 54 /* transmit */ 55 55 AmdtpTransmitStreamProcessor::AmdtpTransmitStreamProcessor(int port, int framerate, int dimension) 56 : TransmitStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0) 57 , m_dbc(0) { 56 : TransmitStreamProcessor(port, framerate), m_dimension(dimension) 57 , m_last_timestamp(0), m_dbc(0), m_ringbuffer_size_frames(0) 58 { 58 59 59 60 … … 95 96 struct iec61883_packet *packet = (struct iec61883_packet *) data; 96 97 unsigned int nevents=0; 97 98 unsigned long in_time=debugGetCurrentTSC();99 98 100 99 packet->eoh0 = 0; … … 171 170 172 171 // FIXME: if m_last_bufferfill > 0 173 int ticks_per_frame=syncmaster->getTicksPerFrame()*1024;172 float ticks_per_frame=syncmaster->getTicksPerFrame(); 174 173 175 174 // m_last_timestamp is the moment upon which the last 'period signal' … … 178 177 // not from the moment the signal was actually given) 179 178 180 // at a period boundary, we expect nb_buffers * periodframes to179 // at a period boundary, we expect m_ringbuffer_size_frames frames to 181 180 // be in the buffers. 'right after' the transfer(), all of these 182 181 // frames should be in the xmit buffers (if transfer() finishes 183 182 // before new packets are received) 184 183 // therefore the last sample of the xmit buffer lies at 185 // T1 = timestamp + (nb_buffers * period) * ticks_per_frame 186 int T1 = m_last_timestamp + (m_nb_buffers * m_period) * ticks_per_frame/1024; 184 // T1 = timestamp + (m_ringbuffer_size_frames) * ticks_per_frame 187 185 188 186 // in reality however life is multithreaded, and we don't know … … 192 190 193 191 // this means that the current sample has timestamp 194 // T2 = T1 - (nb_frames_in_buffer) * ticks_per_frame 195 int buffer_fill=freebob_ringbuffer_read_space(m_event_buffer)/m_dimension/sizeof(quadlet_t); 196 197 int T2 = T1 - buffer_fill * (ticks_per_frame/1024); 198 199 // normally: nb_buffers * period > nb_frames_in_buffer 200 // making T2 > timestamp 201 // however, this isn't always the case, due to ISO buffering etc. 202 // we therefore need to add some extra delay to T2: 203 // T3 = T2 + Tiso 204 // This Tiso has to cope with the prebuffering that has been done 205 // by the ISO layer: e.g. if 100 packets are prebuffered, this 206 // callback is executed approximately 100 packets before the 207 // actual transmission, hence we have to add 100 * 3072 ticks to 208 // the timestamp 209 // we know that one packet occurrs every 1/8000 secs, 210 // therefore the average nb of samples in a packet is m_framerate/8000 211 // making that these 100 packets contain 600 frames, and that 212 // we therefore need to advance the timestamp with the equivalent of 213 // 600 frames (600*ticks_per_frame) 214 int T3 = T2 + (m_handler->getBuffersize() * m_framerate * ticks_per_frame/1024) / 8000; 215 216 // we then need to add the processing delay for the receiving 192 // T2 = T1 - ticks_per_frame * (nb_frames_in_buffer) 193 // = T1 - ticks_per_frame * (m_ringbuffer_size_frames-m_framecounter) 194 // = timestamp + ticks_per_frame * 195 // (m_ringbuffer_size_frames-m_ringbuffer_size_frames+m_framecounter) 196 // = timestamp + ticks_per_frame * m_framecounter 197 198 int T2 = m_last_timestamp + ticks_per_frame*m_framecounter; 199 200 // we then need to add the transfer delay for the receiving 217 201 // device to this time to determine the xmit timestamp 218 // TSTAMP = T 3 + PROCESSING_DELAY202 // TSTAMP = T2 + TRANSFER_DELAY 219 203 220 204 // we should determine when to 'queue' this sample to 221 205 // the ISO xmit layer, based upon the cycle parameter 222 206 // we can define the ideal time at which to send the sample as 223 // TSEND = TSTAMP - PROCESSING_DELAY 224 // being T3 225 // however, this might make things a little too tight, as it can 226 // be that we are pre-queueing things. We have to make sure that 227 // T3 > timestamp (causality on our side) 228 // and that TSTAMP > timestamp (causality on the receiver's side) 229 230 // so we define TSEND as: 231 // TSEND = T3 + Tslack 232 // Tslack tbd 233 234 // note: Tslack=0 packets 235 int TSEND = T3; 236 237 // the xmit timestamp should then be the TSEND + PROCESSING_DELAY 238 int timestamp = TSEND + TRANSMIT_PROCESSING_DELAY; 207 // TSEND = TSTAMP - TRANSFER_DELAY 208 // being T2 209 int TSEND = T2; 210 211 // the xmit timestamp should then be the TSEND + TRANSMIT_TRANSFER_DELAY 212 // note that in this setup, TRANSMIT_TRANSFER_DELAY has to incorporate the 213 // iso buffering 214 int timestamp = TSEND + TRANSMIT_TRANSFER_DELAY; 239 215 240 216 // if we take a look at TSEND we can determine if we are to send … … 251 227 int cycle_wo_wraparound=cycle; 252 228 253 // arbitrary 254 if (cycle_wo_wraparound - (TSEND/3072) < -4000) { 255 cycle_wo_wraparound +=8000; 256 // debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"wraparound detected: %d %d %d\n",cycle, cycle_wo_wraparound, cycle - (TSEND/3072)); 229 int TSEND_cycle_wo_wraparound = TICKS_TO_CYCLES(TSEND); 230 231 // arbitrary, should be replaced by a better wraparound 232 // detection 233 234 // if cycles wraps around, and TSEND_cyles doesn't, 235 // we need to make sure that we compare the right things 236 // i.e. unwrap the cycle parameter 237 // if both wrap, this can't be true 238 if (cycle_wo_wraparound - TSEND_cycle_wo_wraparound < -4000) { 239 cycle_wo_wraparound += 8000; 240 241 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"wraparound on cycle detected: %d %d %d\n", 242 cycle, cycle_wo_wraparound, 243 cycle - TSEND_cycle_wo_wraparound); 244 } 245 246 // if TSEND_cycle wraps around and cycle doesn't, 247 // TSEND_cycle suddenly becomes a lot smaller than cycle 248 if (TSEND_cycle_wo_wraparound - cycle_wo_wraparound < -4000) { 249 TSEND_cycle_wo_wraparound += 8000; 250 251 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"wraparound on TSEND detected: %d %d %d\n", 252 TICKS_TO_CYCLES(TSEND), TSEND_cycle_wo_wraparound, 253 TSEND_cycle_wo_wraparound - cycle_wo_wraparound); 257 254 } 258 255 259 if (TSEND < cycle_wo_wraparound*3072) {256 if (TSEND_cycle_wo_wraparound < cycle_wo_wraparound) { 260 257 nevents=m_syt_interval; 261 258 m_dbc += m_syt_interval; 262 #ifdef DEBUG 263 if(timestamp<cycle_wo_wraparound*3072) { 264 unsigned int tmpsyt_cycles=timestamp/3072; 265 unsigned int tmpsyt_ticks=timestamp%3072; 266 unsigned int tmpsyt = (tmpsyt_cycles << 12) | tmpsyt_ticks; 267 268 debugWarning("Timestamp for cycle %d lies %d ticks in the past: %2u cycles + %04u ticks!\n", 269 cycle, cycle_wo_wraparound*3072-timestamp, 270 CYCLE_COUNTER_GET_CYCLES(tmpsyt), 271 CYCLE_COUNTER_GET_TICKS(tmpsyt)); 272 } 273 #endif 274 259 275 260 } else { // no-data 276 261 … … 286 271 *tag = IEC61883_TAG_WITH_CIP; 287 272 *sy = 0; 288 289 if(packet->dbs) {273 274 // if(packet->dbs) { 290 275 // debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 291 276 // "XMT %04d: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d (%2d)\n", … … 297 282 // *length, 298 283 // ((*length / sizeof (quadlet_t)) - 2)/packet->dbs); 299 }284 // } 300 285 301 286 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Sending empty packet on cycle %d\n", cycle); … … 348 333 } 349 334 350 351 335 // we can forget the seconds for the cycle counter 352 336 // because we are masking with 0xFFFF 353 unsigned int timestamp_cycles=timestamp/3072; 354 unsigned int timestamp_ticks=timestamp%3072; 355 timestamp_cycles %= 8000; 356 357 unsigned int timestamp_cyclecounter = (timestamp_cycles << 12) | timestamp_ticks; 358 359 packet->syt = ntohs(timestamp_cyclecounter & 0xffff); 337 338 unsigned int timestamp_SYT = (TICKS_TO_CYCLES(timestamp) << 12) 339 | TICKS_TO_OFFSET(timestamp); 340 341 packet->syt = ntohs(timestamp_SYT & 0xffff); 360 342 361 343 // debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"XMIT %d EVENTS, SYT %04X for cycle %2d: %08d (%2u cycles + %04u ticks)\n", 362 // nevents, timestamp_cyclecounter & 0xFFFF, cycle, 363 // CYCLE_COUNTER_TO_TICKS(timestamp_cyclecounter), 364 // CYCLE_COUNTER_GET_CYCLES(timestamp_cyclecounter), 365 // CYCLE_COUNTER_GET_TICKS(timestamp_cyclecounter) 344 // nevents, timestamp_SYT & 0xFFFF, cycle, timestamp_SYT 345 // CYCLE_COUNTER_GET_CYCLES(timestamp_SYT), 346 // CYCLE_COUNTER_GET_OFFSET(timestamp_SYT) 366 347 // ); 367 348 } … … 391 372 #endif 392 373 393 m_PacketStat.mark(debugGetCurrentTSC()-in_time);394 // m_PacketStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension));395 // debugOutput(DEBUG_LEVEL_VERBOSE, "XMIT took: %d\n",debugGetCurrentTSC()-in_time);396 374 return retval; 397 375 … … 426 404 //return (m_framecounter > m_period); 427 405 } 428 406 429 407 bool AmdtpTransmitStreamProcessor::prefill() { 430 int i=m_nb_buffers; 408 409 if(!transferSilence(m_ringbuffer_size_frames)) { 410 debugFatal("Could not prefill transmit stream\n"); 411 return false; 412 } 413 414 /* int i=m_nb_buffers; 431 415 while(i--) { 432 416 if(!transferSilence(m_period)) { … … 438 422 // and we should also provide enough prefill for the 439 423 // SYT processing delay 440 // if(!transferSilence((m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND)) {441 // debugFatal("Could not prefill transmit stream\n");442 //return false;443 //}444 424 if(!transferSilence(RECEIVE_PROCESSING_DELAY_IN_SAMPLES)) { 425 debugFatal("Could not prefill transmit stream (2)\n"); 426 return false; 427 } 428 */ 445 429 // the framecounter should be pulled back to 446 430 // make sure the ISO buffering is used … … 538 522 539 523 // allocate the event buffer 540 unsigned intringbuffer_size_frames=m_nb_buffers * m_period;524 m_ringbuffer_size_frames=m_nb_buffers * m_period; 541 525 542 526 // add the processing delay 543 ringbuffer_size_frames+=(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND;527 m_ringbuffer_size_frames+=RECEIVE_PROCESSING_DELAY_IN_SAMPLES; 544 528 545 529 if( !(m_event_buffer=freebob_ringbuffer_create( 546 (m_dimension * ringbuffer_size_frames) * sizeof(quadlet_t)))) {530 (m_dimension * m_ringbuffer_size_frames) * sizeof(quadlet_t)))) { 547 531 debugFatal("Could not allocate memory event ringbuffer"); 548 532 // return -ENOMEM; … … 1005 989 1006 990 AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension) 1007 : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0) {991 : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0), m_one_period_passed(false) { 1008 992 1009 993 … … 1053 1037 // signal that we're running 1054 1038 if(nevents) m_running=true; 1055 1056 // don't process the stream when it is not enabled. 1039 1040 1041 // do the time stamp processing 1042 // put the last time stamp a variable 1043 // this will allow us to determine the 1044 // actual presentation time later 1045 bool wraparound_occurred=false; 1046 1047 m_last_timestamp2=m_last_timestamp; 1048 1049 unsigned int syt_timestamp=ntohs(packet->syt); 1050 // reconstruct the top part of the timestamp using the current cycle number 1051 unsigned int now_cycle_masked=cycle & 0xF; 1052 unsigned int syt_cycle=CYCLE_COUNTER_GET_CYCLES(syt_timestamp); 1053 1054 // if this is true, wraparound has occurred, undo this wraparound 1055 if(syt_cycle<now_cycle_masked) syt_cycle += 0x10; 1056 1057 unsigned int delta_cycles=syt_cycle-now_cycle_masked; 1058 1059 // reconstruct the cycle part of the timestamp 1060 unsigned int new_cycles=cycle + delta_cycles; 1061 1062 if(new_cycles>7999) { 1063 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Detected wraparound: %d + %d = %d\n",cycle,delta_cycles,new_cycles); 1064 1065 new_cycles-=8000; // wrap around 1066 wraparound_occurred=true; 1067 } 1068 1069 m_last_timestamp = (new_cycles) << 12; 1070 1071 // now add the offset part on top of that 1072 m_last_timestamp |= (syt_timestamp & 0xFFF); 1073 1074 // mask off the seconds field 1075 1076 // m_last_timestamp timestamp now contains all info, 1077 // including cycle number 1078 1079 if (m_last_timestamp && m_last_timestamp2) { 1080 // try and estimate the frame rate from the device: 1081 int measured_difference=((int)(CYCLE_COUNTER_TO_TICKS(m_last_timestamp))) 1082 -((int)(CYCLE_COUNTER_TO_TICKS(m_last_timestamp2))); 1083 1084 // handle wrap around of the cycle variable if nescessary 1085 // it can be that two successive timestamps cause wraparound 1086 // (if the difference between time stamps is larger than 2 cycles), 1087 // thus it isn't always nescessary 1088 if (wraparound_occurred & (m_last_timestamp<m_last_timestamp2)) { 1089 debugOutput(DEBUG_LEVEL_VERY_VERBOSE," => correcting for timestamp difference wraparound\n"); 1090 measured_difference+=TICKS_PER_SECOND; 1091 } 1092 1093 // implement a 1st order DLL to estimate the framerate 1094 // this is the number of ticks between two samples 1095 float f=measured_difference; 1096 float err = f / (1.0*m_syt_interval) - m_ticks_per_frame; 1097 1098 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT: %08X | STMP: %08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, f,m_ticks_per_frame,err); 1099 1100 #ifdef DEBUG 1101 if(f > 1.5*((TICKS_PER_SECOND*1.0) / m_framerate)*m_syt_interval) { 1102 debugWarning("Timestamp diff more than 50%% of the nominal diff too large!\n"); 1103 debugWarning(" SYT: %08X | STMP: %08X,%08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, m_last_timestamp2, f,m_ticks_per_frame,err); 1104 } 1105 if(f < 0.5*((TICKS_PER_SECOND*1.0) / m_framerate)*m_syt_interval) { 1106 debugWarning("Timestamp diff more than 50%% of the nominal diff too small!\n"); 1107 debugWarning(" SYT: %08X | STMP: %08X,%08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, m_last_timestamp2, f,m_ticks_per_frame,err); 1108 } 1109 #endif 1110 1111 // integrate the error 1112 m_ticks_per_frame += RECEIVE_DLL_INTEGRATION_COEFFICIENT*err; 1113 1114 } 1115 1116 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"R-SYT for cycle (%2d %2d)=>%2d: %5uT (%04uC + %04uT) %04X %04X %d\n", 1117 cycle,now_cycle_masked,delta_cycles, 1118 CYCLE_COUNTER_TO_TICKS(m_last_timestamp), 1119 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), 1120 CYCLE_COUNTER_GET_OFFSET(m_last_timestamp), 1121 ntohs(packet->syt),m_last_timestamp&0xFFFF, dropped 1122 ); 1123 1124 #ifdef DEBUG 1125 if(m_last_timestamp<m_last_timestamp2) { 1126 if(wraparound_occurred) { 1127 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"timestamp not sequential for cycle %d, but it's wraparound. %08X %08X %08X\n",cycle,syt_timestamp, m_last_timestamp, m_last_timestamp2); 1128 } else { 1129 debugWarning("timestamp not sequential for cycle %d! %08X %08X %08X\n", cycle, syt_timestamp, m_last_timestamp, m_last_timestamp2); 1130 1131 // the DLL will recover from this. 1132 // ??? m_last_timestamp2=m_last_timestamp-(m_syt_interval*m_ticks_per_frame); 1133 } 1134 } 1135 #endif 1136 1137 // don't process the stream samples when it is not enabled. 1057 1138 if(m_disabled) { 1058 1139 return RAW1394_ISO_DEFER; … … 1078 1159 retval=RAW1394_ISO_DEFER; 1079 1160 } 1080 1081 // do the time stamp processing 1082 // put the last time stamp a variable 1083 // this will allow us to determine the 1084 // actual presentation time later 1085 if (packet->syt != 0xFFFF) { 1086 1087 bool wraparound_occurred=false; 1088 1089 m_last_timestamp2=m_last_timestamp; 1090 1091 unsigned int syt_timestamp=ntohs(packet->syt); 1092 // reconstruct the top part of the timestamp using the current cycle number 1093 unsigned int now_cycle_masked=cycle & 0xF; 1094 unsigned int syt_cycle=CYCLE_COUNTER_GET_CYCLES(syt_timestamp); 1095 1096 // if this is true, wraparound has occurred, undo this wraparound 1097 if(syt_cycle<now_cycle_masked) syt_cycle += 0x10; 1098 1099 unsigned int delta_cycles=syt_cycle-now_cycle_masked; 1100 1101 // reconstruct the cycle part of the timestamp 1102 unsigned int new_cycles=cycle + delta_cycles; 1103 1104 if(new_cycles>7999) { 1105 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Detected wraparound: %d + %d = %d\n",cycle,delta_cycles,new_cycles); 1106 1107 new_cycles-=8000; // wrap around 1108 wraparound_occurred=true; 1109 } 1110 1111 m_last_timestamp = (new_cycles) << 12; 1112 1113 // now add the offset part on top of that 1114 m_last_timestamp |= (syt_timestamp & 0xFFF); 1115 1116 // mask off the seconds field 1117 1118 // m_last_timestamp timestamp now contains all info, 1119 // including cycle number 1120 1121 if (m_last_timestamp & m_last_timestamp2) { 1122 // try and estimate the frame rate from the device: 1123 int timestamp_difference=((int)(CYCLE_COUNTER_TO_TICKS(m_last_timestamp))) 1124 -((int)(CYCLE_COUNTER_TO_TICKS(m_last_timestamp2))); 1125 1126 // handle wrap around of the cycle variable if nescessary 1127 // it can be that two successive timestamps cause wraparound (if the difference between time 1128 // stamps is larger than 2 cycles), thus it isn't always nescessary 1129 if (wraparound_occurred & (m_last_timestamp<m_last_timestamp2)) { 1130 debugOutput(DEBUG_LEVEL_VERY_VERBOSE," => correcting for timestamp difference wraparound\n"); 1131 timestamp_difference+=TICKS_PER_SECOND; 1132 } 1133 1134 // implement a 1st order DLL to estimate the framerate 1135 // this is the number of ticks between two samples 1136 float f=timestamp_difference; 1137 float err = timestamp_difference / m_syt_interval; 1138 // now it contains the error between our estimate 1139 // and the current measurement 1140 err=err-m_ticks_per_frame; 1141 1142 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT: %08X | STMP: %08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, f,m_ticks_per_frame,err); 1143 1144 #ifdef DEBUG 1145 if(f > 1.5*((TICKS_PER_SECOND*1.0) / m_framerate)*m_syt_interval) { 1146 debugWarning("Timestamp diff more than 50%% of the nominal diff too large!\n"); 1147 debugWarning(" SYT: %08X | STMP: %08X,%08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, m_last_timestamp2, f,m_ticks_per_frame,err); 1148 } 1149 if(f < 0.5*((TICKS_PER_SECOND*1.0) / m_framerate)*m_syt_interval) { 1150 debugWarning("Timestamp diff more than 50%% of the nominal diff too small!\n"); 1151 debugWarning(" SYT: %08X | STMP: %08X,%08X | DLL: in=%5.0f, current=%f, err=%e\n",syt_timestamp, m_last_timestamp, m_last_timestamp2, f,m_ticks_per_frame,err); 1152 } 1153 #endif 1154 1155 const float coeff=0.0005; 1156 // integrate the error 1157 m_ticks_per_frame += coeff*err; 1158 1159 } 1160 1161 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"R-SYT for cycle (%2d %2d)=>%2d: %5uT (%04uC + %04uT) %04X %04X %d\n", 1162 cycle,now_cycle_masked,delta_cycles, 1163 CYCLE_COUNTER_TO_TICKS(m_last_timestamp), 1164 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), 1165 CYCLE_COUNTER_GET_TICKS(m_last_timestamp), 1166 ntohs(packet->syt),m_last_timestamp&0xFFFF, dropped 1167 ); 1168 1169 #ifdef DEBUG 1170 if(m_last_timestamp<m_last_timestamp2) { 1171 if(wraparound_occurred) { 1172 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"timestamp not sequential for cycle %d, but it's wraparound. %08X %08X %08X\n",cycle,syt_timestamp, m_last_timestamp, m_last_timestamp2); 1173 } else { 1174 debugWarning("timestamp not sequential for cycle %d! %08X %08X %08X\n", cycle, syt_timestamp, m_last_timestamp, m_last_timestamp2); 1175 1176 // the DLL will recover from this. 1177 m_last_timestamp2=m_last_timestamp; 1178 } 1179 } 1180 #endif 1181 1182 } 1161 1183 1162 } 1184 1163 … … 1223 1202 // this uses SYT to determine if one period is ready 1224 1203 bool AmdtpReceiveStreamProcessor::isOnePeriodReady() { 1225 #define DO_SYT_SYNC 1204 1226 1205 #ifdef DO_SYT_SYNC 1227 1206 // this code is not ready yet … … 1232 1211 // therefore the number of ticks per sample is 24576000 / Fs 1233 1212 // NOTE: this will be rounded!! 1234 float ticks_per_sample=24576000.0/m_framerate; 1213 // float ticks_per_sample=24576000.0/m_framerate; 1214 float ticks_per_sample=m_ticks_per_frame; 1235 1215 1236 1216 // we are allowed to add some constant 1237 1217 // processing delay to the transfer delay 1238 1218 // being the period size and some fixed delay 1239 unsigned int processing_delay=ticks_per_sample*(m_period)+RECEIVE_PROCESSING_DELAY;1240 1219 // unsigned int processing_delay=ticks_per_sample*(m_period)+RECEIVE_PROCESSING_DELAY; 1220 unsigned int processing_delay=ticks_per_sample*(m_period+RECEIVE_PROCESSING_DELAY_IN_SAMPLES); 1241 1221 1242 1222 // the number of events in the buffer is … … 1250 1230 // m_last_timestamp - (m_framecounter-m_syt_interval)*ticks_per_sample 1251 1231 1252 // however we have to make sure that we can transfer at least one period 1232 // NOTE: in fact, we don't have to check this, because it should always be the case 1233 // 1234 // WAS: however we have to make sure that we can transfer at least one period 1253 1235 // therefore we first check if this is ok 1254 1236 1255 if(m_framecounter > (signed int)m_period) {1256 // we make this signed, because this can be < 0 1237 // if(m_framecounter > (signed int)m_period) { 1238 1257 1239 unsigned int m_last_timestamp_ticks = CYCLE_COUNTER_TO_TICKS(m_last_timestamp); 1258 1240 1259 1241 // add the processing delay 1260 1242 int ideal_presentation_time = m_last_timestamp_ticks + processing_delay; 1261 unsigned int buffer_content_ticks=(int)((m_framecounter-m_syt_interval)*ticks_per_sample); 1243 int buffer_content_ticks=((int)m_framecounter)-((int)m_syt_interval); 1244 buffer_content_ticks *= ticks_per_sample; 1262 1245 1263 1246 // if the ideal_presentation_time is smaller than buffer_content_ticks, wraparound has occurred … … 1270 1253 // FIXME: if we are sure, make ideal_presentation_time an unsigned int 1271 1254 // assert(ideal_presentation_time>=0); 1255 1256 unsigned int current_time_ticks = (m_handler->getCycleCounter() % TICKS_PER_SECOND ); 1257 1272 1258 #ifdef DEBUG 1273 1259 if(ideal_presentation_time<0) { 1274 1260 debugWarning("ideal_presentation_time time is negative!\n"); 1261 debugOutput(DEBUG_LEVEL_VERBOSE,"Periods: %d, FC: %d, remote framerate %f\n", 1262 m_PeriodStat.m_count, m_framecounter, m_ticks_per_frame); 1263 debugOutput(DEBUG_LEVEL_VERBOSE,"p-delay: %u, buffer_content: %d\n", 1264 processing_delay, buffer_content_ticks); 1265 debugOutput(DEBUG_LEVEL_VERBOSE,"Timestamp : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n", 1266 m_last_timestamp_ticks, 1267 CYCLE_COUNTER_GET_SECS(m_last_timestamp), 1268 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), 1269 CYCLE_COUNTER_GET_OFFSET(m_last_timestamp) 1270 ); 1271 debugOutput(DEBUG_LEVEL_VERBOSE,"P-TIME : %10d ticks (%3u secs + %4u cycles + %04u ticks)\n", 1272 ideal_presentation_time, 1273 TICKS_TO_SECS(ideal_presentation_time), 1274 TICKS_TO_CYCLES(ideal_presentation_time), 1275 TICKS_TO_OFFSET(ideal_presentation_time) 1276 ); 1277 debugOutput(DEBUG_LEVEL_VERBOSE,"Now : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n", 1278 current_time_ticks, 1279 TICKS_TO_SECS(current_time_ticks), 1280 TICKS_TO_CYCLES(current_time_ticks), 1281 TICKS_TO_OFFSET(current_time_ticks) 1282 ); 1283 return false; 1284 } 1285 if(ideal_presentation_time<m_last_timestamp_ticks) { 1286 debugWarning("ideal_presentation_time earlier than last timestamp!\n"); 1287 debugOutput(DEBUG_LEVEL_VERBOSE,"Periods: %d, FC: %d, remote framerate %f\n", 1288 m_PeriodStat.m_count, m_framecounter, m_ticks_per_frame); 1289 debugOutput(DEBUG_LEVEL_VERBOSE,"p-delay: %u, buffer_content: %u\n", 1290 processing_delay, buffer_content_ticks); 1291 debugOutput(DEBUG_LEVEL_VERBOSE,"Timestamp : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n", 1292 m_last_timestamp_ticks, 1293 CYCLE_COUNTER_GET_SECS(m_last_timestamp), 1294 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), 1295 CYCLE_COUNTER_GET_OFFSET(m_last_timestamp) 1296 ); 1297 debugOutput(DEBUG_LEVEL_VERBOSE,"P-TIME : %10d ticks (%3u secs + %4u cycles + %04u ticks)\n", 1298 ideal_presentation_time, 1299 TICKS_TO_SECS(ideal_presentation_time), 1300 TICKS_TO_CYCLES(ideal_presentation_time), 1301 TICKS_TO_OFFSET(ideal_presentation_time) 1302 ); 1303 debugOutput(DEBUG_LEVEL_VERBOSE,"Now : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n", 1304 current_time_ticks, 1305 TICKS_TO_SECS(current_time_ticks), 1306 TICKS_TO_CYCLES(current_time_ticks), 1307 TICKS_TO_OFFSET(current_time_ticks) 1308 ); 1309 1275 1310 } 1276 1311 #endif 1277 1312 1278 unsigned int current_time=m_handler->getCycleCounter() & 0x1FFFFFF;1279 unsigned int current_time_ticks = CYCLE_COUNTER_TO_TICKS(current_time);1280 1281 1313 // if the last signalled period lies in the future, we know we had wraparound of the clock 1282 1314 // so add one second … … 1287 1319 CYCLE_COUNTER_GET_SECS(m_last_timestamp), 1288 1320 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), 1289 CYCLE_COUNTER_GET_ TICKS(m_last_timestamp)1321 CYCLE_COUNTER_GET_OFFSET(m_last_timestamp) 1290 1322 ); 1291 1323 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"P-TIME : %10d ticks (%3u secs + %4u cycles + %04u ticks)\n", … … 1297 1329 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Now : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n", 1298 1330 current_time_ticks, 1299 CYCLE_COUNTER_GET_SECS(current_time),1300 CYCLE_COUNTER_GET_CYCLES(current_time),1301 CYCLE_COUNTER_GET_TICKS(current_time)1331 TICKS_TO_SECS(current_time_ticks), 1332 TICKS_TO_CYCLES(current_time_ticks), 1333 TICKS_TO_OFFSET(current_time_ticks) 1302 1334 ); 1303 1335 … … 1312 1344 if(tmp<0) { 1313 1345 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT passed (%d ticks too late)\n",-tmp); 1314 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Periods: %d, remote ticks/frame: %f, remote framerate = %f\n",m_PeriodStat.m_count, m_ticks_per_frame, 24576000.0/m_ticks_per_frame); 1346 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Periods: %d, remote ticks/frame: %f, remote framerate = %f\n", 1347 m_PeriodStat.m_count, m_ticks_per_frame, 24576000.0/m_ticks_per_frame); 1348 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Bufferfill %d, framecounter %d\n", 1349 freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension),m_framecounter); 1315 1350 if (-tmp>1000000) debugWarning("SYT VERY LATE: %d!\n",-tmp); 1316 1351 1352 m_WakeupStat.mark(m_framecounter); 1353 1354 m_one_period_passed=true; 1317 1355 m_last_timestamp_at_period_ticks=ideal_presentation_time; 1318 return true; 1356 1357 return true; 1319 1358 } else { 1320 1359 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Too early wait %d ticks\n",tmp); 1321 1360 return false; 1322 1361 } 1323 } else {1324 return false;1325 }1362 // } else { 1363 // return false; 1364 // } 1326 1365 #else 1327 1366 if(m_framecounter > m_period) { … … 1331 1370 } 1332 1371 1372 unsigned int AmdtpReceiveStreamProcessor::getPeriodTimeStamp() { 1373 if (m_one_period_passed) { 1374 return m_last_timestamp_at_period_ticks; 1375 } else { 1376 // float ticks_per_sample=24576000.0/m_framerate; 1377 float ticks_per_sample=m_ticks_per_frame; 1378 1379 // we are allowed to add some constant 1380 // processing delay to the transfer delay 1381 // being the period size and some fixed delay 1382 // unsigned int processing_delay=ticks_per_sample*(m_period)+RECEIVE_PROCESSING_DELAY; 1383 unsigned int processing_delay=ticks_per_sample*(m_period+RECEIVE_PROCESSING_DELAY_IN_SAMPLES); 1384 1385 unsigned int m_last_timestamp_ticks = CYCLE_COUNTER_TO_TICKS(m_last_timestamp); 1386 1387 // add the processing delay 1388 int ideal_presentation_time = m_last_timestamp_ticks + processing_delay; 1389 unsigned int buffer_content_ticks=(int)((m_framecounter-m_syt_interval)*ticks_per_sample); 1390 1391 // if the ideal_presentation_time is smaller than buffer_content_ticks, wraparound has occurred 1392 // for the cycle part of m_last_timestamp. Therefore add one second worth of ticks 1393 // to the cycle counter, as this is the wraparound point. 1394 if (ideal_presentation_time < buffer_content_ticks) ideal_presentation_time += 24576000; 1395 // we can now safely substract these, it will always be > 0 1396 ideal_presentation_time -= buffer_content_ticks; 1397 1398 return ideal_presentation_time; 1399 } 1400 } 1401 1333 1402 void AmdtpReceiveStreamProcessor::dumpInfo() 1334 1403 { … … 1371 1440 m_last_timestamp2=0; 1372 1441 1442 m_one_period_passed=false; 1373 1443 1374 1444 // reset all non-device specific stuff … … 1429 1499 1430 1500 // add the processing delay 1431 debugOutput(DEBUG_LEVEL_VERBOSE,"Adding %u frames of SYT slack buffering...\n",(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND); 1432 ringbuffer_size_frames+=(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND; 1501 debugOutput(DEBUG_LEVEL_VERBOSE,"Adding %u frames of SYT slack buffering...\n", 1502 RECEIVE_PROCESSING_DELAY_IN_SAMPLES); 1503 ringbuffer_size_frames+=RECEIVE_PROCESSING_DELAY_IN_SAMPLES; 1433 1504 1434 1505 if( !(m_event_buffer=freebob_ringbuffer_create( 1435 1506 (m_dimension * ringbuffer_size_frames) * sizeof(quadlet_t)))) { 1436 1507 debugFatal("Could not allocate memory event ringbuffer"); 1437 // return -ENOMEM;1438 1508 return false; 1439 1509 } … … 1443 1513 debugFatal("Could not allocate temporary cluster buffer"); 1444 1514 freebob_ringbuffer_free(m_event_buffer); 1445 // return -ENOMEM;1446 1515 return false; 1447 1516 } trunk/libfreebob/src/libstreaming/AmdtpStreamProcessor.h
r266 r360 141 141 unsigned int offset, unsigned int nevents); 142 142 143 unsigned intm_last_timestamp;143 unsigned long m_last_timestamp; 144 144 145 145 unsigned int m_dbc; 146 147 unsigned int m_ringbuffer_size_frames; 146 148 147 149 DECLARE_DEBUG_MODULE; … … 193 195 194 196 float getTicksPerFrame() {return m_ticks_per_frame;}; 195 unsigned int getPeriodTimeStamp() {return m_last_timestamp_at_period_ticks;};196 197 unsigned int getPeriodTimeStamp(); 198 197 199 void dumpInfo(); 198 200 … … 215 217 float m_ticks_per_frame; 216 218 219 bool m_one_period_passed; 220 217 221 DECLARE_DEBUG_MODULE; 218 222 trunk/libfreebob/src/libstreaming/freebob_streaming.cpp
r336 r360 86 86 if ( !dev->m_deviceManager ) { 87 87 debugFatal( "Could not allocate device manager\n" ); 88 88 delete dev; 89 89 return 0; 90 90 } … … 92 92 debugFatal( "Could not initialize device manager\n" ); 93 93 delete dev->m_deviceManager; 94 94 delete dev; 95 95 return 0; 96 96 } … … 101 101 if(!dev->processorManager) { 102 102 debugFatal("Could not create StreamProcessorManager\n"); 103 103 delete dev->m_deviceManager; 104 104 delete dev; 105 105 return 0; … … 112 112 debugFatal("Could not init StreamProcessorManager\n"); 113 113 delete dev->processorManager; 114 114 delete dev->m_deviceManager; 115 115 delete dev; 116 116 return 0; … … 120 120 if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 121 121 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not discover devices\n"); 122 delete dev->processorManager; 123 delete dev->m_deviceManager; 124 delete dev; 122 125 return 0; 123 126 } … … 131 134 // Set the device's sampling rate to that requested 132 135 // FIXME: does this really belong here? If so we need to handle errors. 133 device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate)); 136 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 137 // try again: 138 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 139 delete dev->processorManager; 140 delete dev->m_deviceManager; 141 delete dev; 142 debugFatal("Could not set sampling frequency to %d\n",dev->options.sample_rate); 143 return 0; 144 } 145 } 134 146 135 147 // prepare the device … … 156 168 debugOutput(DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 157 169 158 dev->processorManager->prepare(); 170 if (!dev->processorManager->prepare()) { 171 debugFatal("Could not prepare streaming...\n"); 172 return false; 173 } 159 174 160 175 return true; trunk/libfreebob/src/libstreaming/IsoHandler.cpp
r341 r360 29 29 #include "IsoHandler.h" 30 30 #include "IsoStream.h" 31 #include "cyclecounter.h" 32 33 #include "libutil/Time.h" 34 #include "libutil/TimeSource.h" 35 #include "libutil/SystemTimeSource.h" 36 31 37 #include <errno.h> 32 38 #include <netinet/in.h> … … 36 42 #include <iostream> 37 43 using namespace std; 44 45 46 #define CC_SLEEP_TIME_AFTER_UPDATE 100 47 #define CC_SLEEP_TIME_AFTER_FAILURE 10 48 #define CC_DLL_COEFF ((0.01)*((float)(CC_SLEEP_TIME_AFTER_UPDATE/1000.0))) 49 50 #define CC_MAX_RATE_ERROR (2/100.0) 51 #define CC_INIT_MAX_TRIES 10 38 52 39 53 … … 79 93 80 94 /* Base class implementation */ 95 IsoHandler::IsoHandler(int port) 96 : TimeSource(), m_handle(0), m_handle_util(0), m_port(port), 97 m_buf_packets(400), m_max_packet_size(1024), m_irq_interval(-1), 98 m_cyclecounter_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576), 99 m_ticks_per_usec_dll_err2(0), 100 m_packetcount(0), m_dropped(0), m_Client(0) 101 { 102 InitTime(); 103 m_TimeSource=new FreebobUtil::SystemTimeSource(); 104 } 105 106 IsoHandler::IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq) 107 : TimeSource(), m_handle(0), m_port(port), 108 m_buf_packets(buf_packets), m_max_packet_size( max_packet_size), 109 m_irq_interval(irq), 110 m_cyclecounter_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576), 111 m_ticks_per_usec_dll_err2(0), 112 m_packetcount(0), m_dropped(0), m_Client(0) 113 { 114 InitTime(); 115 m_TimeSource=new FreebobUtil::SystemTimeSource(); 116 } 81 117 82 118 IsoHandler::~IsoHandler() { … … 87 123 if(m_handle_util) raw1394_destroy_handle(m_handle_util); 88 124 125 delete m_TimeSource; 89 126 } 90 127 … … 127 164 raw1394_set_bus_reset_handler(m_handle, busreset_handler); 128 165 166 // initialize the local timesource 167 m_TimeSource_NbCycleWraps=0; 168 quadlet_t buf=0; 169 unsigned int new_counter; 170 171 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 172 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 173 174 new_counter= ntohl(buf) & 0xFFFFFFFF; 175 m_TimeSource_LastSecs=CYCLE_COUNTER_GET_SECS(new_counter); 176 129 177 // update the cycle counter value for initial value 130 updateCycleCounter(); 131 132 return true; 178 initCycleCounter(); 179 180 return true; 181 } 182 183 bool 184 IsoHandler::setSyncMaster(FreebobUtil::TimeSource *t) 185 { 186 m_TimeSource=t; 187 188 // update the cycle counter value for initial value 189 initCycleCounter(); 190 191 return true; 133 192 } 134 193 … … 141 200 142 201 /** 143 * Returns the current value of the cycle counter202 * Bus reset handler 144 203 * 145 * @return the current value of the cycle counter204 * @return ? 146 205 */ 147 #define CSR_CYCLE_TIME 0x200 148 #define CSR_REGISTER_BASE 0xfffff0000000ULL 149 150 #define CYCLE_COUNTER_GET_SECS(x) (((x & 0xFE000000) >> 25)) 151 #define CYCLE_COUNTER_GET_CYCLES(x) (((x & 0x01FFF000) >> 12)) 152 #define CYCLE_COUNTER_GET_TICKS(x) (((x & 0x00000FFF))) 153 #define CYCLE_COUNTER_TO_TICKS(x) ((CYCLE_COUNTER_GET_SECS(x) * 24576000) +\ 154 (CYCLE_COUNTER_GET_CYCLES(x) * 3072) +\ 155 (CYCLE_COUNTER_GET_TICKS(x) )) 206 207 int IsoHandler::handleBusReset(unsigned int generation) { 208 debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 209 210 // as busreset can elect a new cycle master, 211 // we need to re-initialize our timing code 212 initCycleCounter(); 213 214 return 0; 215 } 216 217 /** 218 * Returns the current value of the cycle counter (in ticks) 219 * 220 * @return the current value of the cycle counter (in ticks) 221 */ 156 222 157 223 unsigned int IsoHandler::getCycleCounter() { 158 return m_cyclecounter; 159 } 160 161 void IsoHandler::updateCycleCounter() { 224 // calculate the cycle counter based upon the current time 225 // and the estimated tick rate 226 freebob_microsecs_t now=m_TimeSource->getCurrentTimeAsUsecs(); 227 228 // linear interpolation 229 int delta_usecs=now-m_lastmeas_usecs; 230 231 float offset=m_ticks_per_usec * ((float)delta_usecs); 232 233 unsigned int pred_ticks=m_cyclecounter_ticks+(unsigned int)offset; 234 235 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Get CC: d_usecs=%d, offset=%f, cc_ticks=%lu, pred_ticks=%lu\n", 236 delta_usecs, offset, m_cyclecounter_ticks,pred_ticks 237 ); 238 239 // if we need to wrap, do it 240 if (pred_ticks > TICKS_PER_SECOND * 128) { 241 pred_ticks -= TICKS_PER_SECOND * 128; 242 } 243 244 return pred_ticks; 245 } 246 247 bool IsoHandler::updateCycleCounter() { 162 248 quadlet_t buf=0; 249 250 freebob_microsecs_t prev_usecs=m_lastmeas_usecs; 251 unsigned int prev_ticks=m_cyclecounter_ticks; 252 253 freebob_microsecs_t new_usecs; 254 unsigned int new_ticks; 255 unsigned int new_counter; 256 257 /* To estimate the cycle counter, we implement a 258 DLL based routine, that maps the cycle counter 259 on the system clock. 260 261 For more info, refer to: 262 "Using a DLL to filter time" 263 Fons Adriaensen 264 265 Can be found at: 266 http://users.skynet.be/solaris/linuxaudio/downloads/usingdll.pdf 267 or maybe at: 268 http://www.kokkinizita.net/linuxaudio 269 270 Basically what we do is estimate the next point (T1,CC1_est) 271 based upon the previous point (T0, CC0) and the estimated rate (R). 272 Then we compare our estimation with the measured cycle counter 273 at T1 (=CC1_meas). We then calculate the estimation error on R: 274 err=(CC1_meas-CC0)/(T1-T2) - (CC1_est-CC0)/(T1-T2) 275 and try to minimize this on average (DLL) 276 277 Note that in order to have a contignous mapping, we should 278 update CC0<=CC1_est instead of CC0<=CC1_meas. The measurement 279 serves only to correct the error 'on average'. 280 281 In the code, the following variable names are used: 282 T0=prev_usecs 283 T1=next_usecs 284 285 CC0=prev_ticks 286 CC1_est=est_ticks 287 CC1_meas=meas_ticks 288 289 */ 163 290 164 291 // normally we should be able to use the same handle … … 167 294 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 168 295 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 169 170 m_cyclecounter= ntohl(buf) & 0xFFFFFFFF; 171 172 // debugOutput(DEBUG_LEVEL_VERBOSE,"Updating timestamp: %08X (%2u sec + %2u cycles + %04u ticks)\n", 173 // m_cyclecounter, 174 // CYCLE_COUNTER_GET_SECS(m_cyclecounter), 175 // CYCLE_COUNTER_GET_CYCLES(m_cyclecounter), 176 // CYCLE_COUNTER_GET_TICKS(m_cyclecounter) 177 // ); 178 179 180 usleep(100); 296 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 297 298 new_counter= ntohl(buf) & 0xFFFFFFFF; 299 new_ticks=CYCLE_COUNTER_TO_TICKS(new_counter); 300 301 // the difference in system time 302 int delta_usecs=new_usecs-prev_usecs; 303 // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should 304 // never return the same value (maybe in future terrahz processors?) 305 assert(delta_usecs); 306 307 // the measured cycle counter difference 308 unsigned int delta_ticks_meas; 309 if (new_ticks > prev_ticks) { 310 delta_ticks_meas=new_ticks - prev_ticks; 311 } else { // wraparound 312 delta_ticks_meas=CYCLE_COUNTER_UNWRAP_TICKS(new_ticks) - prev_ticks; 313 } 314 315 // the estimated cycle counter difference 316 unsigned int delta_ticks_est=(unsigned int)(m_ticks_per_usec * ((float)delta_usecs)); 317 318 // the measured & estimated rate 319 float rate_meas=((float)delta_ticks_meas/(float)delta_usecs); 320 float rate_est=((float)m_ticks_per_usec); 321 322 // these make sure we don't update when the measurement is 323 // bad. We know the nominal rate, and it can't be that far 324 // off. The thing is that there is a problem in measuring 325 // both usecs and ticks at the same time (no provision in 326 // the kernel. 327 // We know that there are some tolerances on both 328 // the system clock and the firewire clock such that the 329 // actual difference is rather small. So we discard values 330 // that are too far from the nominal rate. 331 // Otherwise the DLL has to have a very low bandwidth, in 332 // order not to be desturbed too much by these bad measurements 333 // resulting in very slow locking. 334 335 if ( (rate_meas < 24.576*(1.0+CC_MAX_RATE_ERROR)) 336 && (rate_meas > 24.576*(1.0-CC_MAX_RATE_ERROR))) { 337 338 #ifdef DEBUG 339 340 int diff=(int)delta_ticks_est; 341 342 // calculate the difference in predicted ticks and 343 // measured ticks 344 diff -= delta_ticks_meas; 345 346 347 if (diff > 24000 || diff < -24000) { // approx +/-1 msec error 348 debugOutput(DEBUG_LEVEL_VERBOSE,"Bad pred (%p): diff=%d, dt_est=%u, dt_meas=%u, d=%dus, err=%fus\n", this, 349 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 350 ); 351 } else { 352 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Good pred: diff=%d, dt_est=%u, dt_meas=%u, d=%dus, err=%fus\n", 353 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 354 ); 355 } 356 #endif 357 // DLL the error to obtain the rate. 358 // (note: the DLL makes the error=0) 359 // only update the DLL if the rate is within 10% of the expected 360 // rate 361 float err=rate_meas-rate_est; 362 363 // 2nd order DLL update 364 // const float w=6.28*0.0001; 365 // const float b=w*1.45; 366 // const float c=w*w; 367 // 368 // m_ticks_per_usec += b*err + m_ticks_per_usec_dll_err2; 369 // m_ticks_per_usec_dll_err2 += c * err; 370 371 // first order DLL update 372 m_ticks_per_usec += CC_DLL_COEFF*err; 373 374 if ( (m_ticks_per_usec > 24.576*(1.0+CC_MAX_RATE_ERROR)) 375 || (m_ticks_per_usec < 24.576*(1.0-CC_MAX_RATE_ERROR))) { 376 debugOutput(DEBUG_LEVEL_VERBOSE, "Warning: DLL ticks/usec near clipping (%8.4f)\n", 377 m_ticks_per_usec); 378 } 379 380 // update the internal values 381 // note: the next cyclecounter point is 382 // the estimated one, not the measured one! 383 m_cyclecounter_ticks += delta_ticks_est; 384 // if we need to wrap, do it 385 if (m_cyclecounter_ticks > TICKS_PER_SECOND * 128) { 386 m_cyclecounter_ticks -= TICKS_PER_SECOND * 128; 387 } 388 389 m_lastmeas_usecs = new_usecs; 390 391 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: %10u -> %10u, d=%7uus, dt_est=%7u, dt_meas=%7u, erate=%6.4f, mrate=%6f\n", 392 prev_ticks, m_cyclecounter_ticks, delta_usecs, 393 delta_ticks_est, delta_ticks_meas, m_ticks_per_usec, rate_meas 394 ); 395 396 // the estimate is good 397 return true; 398 } else { 399 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: Not updating, rate out of range (%6.4f)\n", 400 rate_meas 401 ); 402 return false; 403 404 } 405 } 406 407 void IsoHandler::initCycleCounter() { 408 quadlet_t buf=0; 409 410 freebob_microsecs_t prev_usecs; 411 unsigned int prev_ticks; 412 unsigned int prev_counter; 413 414 freebob_microsecs_t new_usecs; 415 unsigned int new_ticks; 416 unsigned int new_counter; 417 418 float rate=0.0; 419 420 unsigned int try_cnt=0; 421 422 // make sure that we start with a decent rate, 423 // meaning that we want two successive (usecs,ticks) 424 // points that make sense. 425 426 while ( (try_cnt++ < CC_INIT_MAX_TRIES) && 427 ( (rate > 24.576*(1.0+CC_MAX_RATE_ERROR)) 428 || (rate < 24.576*(1.0-CC_MAX_RATE_ERROR)))) { 429 430 // normally we should be able to use the same handle 431 // because it is not iterated on by any other stuff 432 // but I'm not sure 433 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 434 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 435 prev_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 436 437 prev_counter= ntohl(buf) & 0xFFFFFFFF; 438 prev_ticks=CYCLE_COUNTER_TO_TICKS(prev_counter); 439 440 usleep(CC_SLEEP_TIME_AFTER_UPDATE); 441 442 // normally we should be able to use the same handle 443 // because it is not iterated on by any other stuff 444 // but I'm not sure 445 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 446 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 447 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 448 449 new_counter= ntohl(buf) & 0xFFFFFFFF; 450 new_ticks=CYCLE_COUNTER_TO_TICKS(new_counter); 451 452 unsigned int delta_ticks; 453 454 if (new_ticks > prev_ticks) { 455 delta_ticks=new_ticks - prev_ticks; 456 } else { // wraparound 457 delta_ticks=CYCLE_COUNTER_UNWRAP_TICKS(new_ticks) - prev_ticks; 458 } 459 460 int delta_usecs=new_usecs-prev_usecs; 461 462 // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should 463 // never return the same value (maybe in future terrahz processors?) 464 assert(delta_usecs); 465 466 rate=((float)delta_ticks/(float)delta_usecs); 467 468 // update the internal values 469 m_cyclecounter_ticks=new_ticks; 470 m_lastmeas_usecs=new_usecs; 471 472 debugOutput(DEBUG_LEVEL_VERBOSE,"Try %d: rate=%6.4f\n", 473 try_cnt,rate 474 ); 475 476 } 477 478 // this is not fatal, the DLL will eventually correct this 479 if(try_cnt == CC_INIT_MAX_TRIES) { 480 debugWarning("Failed to properly initialize cycle counter...\n"); 481 } 482 483 // initialize this to the nominal value 484 m_ticks_per_usec = 24.576; 485 m_ticks_per_usec_dll_err2 = 0; 486 181 487 } 182 488 … … 189 495 debugOutputShort( DEBUG_LEVEL_NORMAL, " Handler type : %s\n", 190 496 (this->getType()==EHT_Receive ? "Receive" : "Transmit")); 191 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : % d, %d\n",497 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : %2d, %2d\n", 192 498 m_port, channel); 193 debugOutputShort( DEBUG_LEVEL_NORMAL, " Packet count : % d (%d dropped)\n\n",499 debugOutputShort( DEBUG_LEVEL_NORMAL, " Packet count : %10d (%5d dropped)\n", 194 500 this->getPacketCount(), this->getDroppedCount()); 501 #ifdef DEBUG 502 unsigned int cc=this->getCycleCounter(); 503 debugOutputShort( DEBUG_LEVEL_NORMAL, " Cycle counter : %10lu (%03us, %04ucycles, %04uticks)\n", 504 cc,TICKS_TO_SECS(cc),TICKS_TO_CYCLES(cc),TICKS_TO_OFFSET(cc)); 505 #endif 506 debugOutputShort( DEBUG_LEVEL_NORMAL, " Ticks/usec : %8.6f (dll2: %8.6e)\n\n", 507 this->getTicksPerUsec(), m_ticks_per_usec_dll_err2); 195 508 196 509 }; … … 235 548 236 549 } 550 551 /* The timesource interface */ 552 freebob_microsecs_t IsoHandler::getCurrentTime() { 553 quadlet_t buf=0; 554 unsigned int new_counter; 555 556 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 557 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 558 559 new_counter= ntohl(buf) & 0xFFFFFFFF; 560 561 // this assumes that it never happens that there are more than 2 562 // minutes between calls 563 if (CYCLE_COUNTER_GET_SECS(new_counter) < m_TimeSource_LastSecs) { 564 m_TimeSource_NbCycleWraps++; 565 } 566 567 freebob_microsecs_t ticks=m_TimeSource_NbCycleWraps * 128 * TICKS_PER_SECOND 568 + CYCLE_COUNTER_TO_TICKS(new_counter); 569 570 m_TimeSource_LastSecs=CYCLE_COUNTER_GET_SECS(new_counter); 571 572 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Wraps=%4u, LastSecs=%3u, nowSecs=%3u, ticks=%10u\n", 573 m_TimeSource_NbCycleWraps, m_TimeSource_LastSecs, 574 CYCLE_COUNTER_GET_SECS(new_counter), ticks 575 ); 576 577 return ticks; 578 } 579 580 freebob_microsecs_t IsoHandler::getCurrentTimeAsUsecs() { 581 float tmp=getCurrentTime(); 582 float tmp2 = tmp * USECS_PER_TICK; 583 freebob_microsecs_t retval=(freebob_microsecs_t)tmp2; 584 585 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"tmp=%f, tmp2=%f, retval=%u\n", 586 tmp, tmp2,retval 587 ); 588 589 return retval; 590 } 591 592 237 593 238 594 /* Child class implementations */ … … 329 685 int IsoRecvHandler::handleBusReset(unsigned int generation) { 330 686 debugOutput( DEBUG_LEVEL_VERBOSE, "handle bus reset...\n"); 687 331 688 //TODO: implement busreset 689 690 // pass on the busreset signal 691 if(IsoHandler::handleBusReset(generation)) { 692 return -1; 693 } 332 694 return 0; 333 695 } … … 439 801 debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 440 802 //TODO: implement busreset 803 804 // pass on the busreset signal 805 if(IsoHandler::handleBusReset(generation)) { 806 return -1; 807 } 808 441 809 return 0; 442 810 } trunk/libfreebob/src/libstreaming/IsoHandler.h
r341 r360 31 31 #include "../debugmodule/debugmodule.h" 32 32 33 #include "libutil/TimeSource.h" 34 33 35 #include <libraw1394/raw1394.h> 34 36 … … 39 41 40 42 class IsoStream; 41 42 43 /*! 43 44 \brief The Base Class for ISO Handlers … … 49 50 */ 50 51 51 class IsoHandler 52 class IsoHandler : public FreebobUtil::TimeSource 52 53 { 53 54 protected: … … 60 61 }; 61 62 62 IsoHandler(int port) 63 : m_handle(0), m_handle_util(0), m_port(port), 64 m_buf_packets(400), m_max_packet_size(1024), m_irq_interval(-1), 65 m_packetcount(0), m_dropped(0), m_Client(0) 66 {} 67 68 IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq) 69 : m_handle(0), m_port(port), 70 m_buf_packets(buf_packets), m_max_packet_size( max_packet_size), 71 m_irq_interval(irq), m_packetcount(0), m_dropped(0), m_Client(0) 72 {} 63 IsoHandler(int port); 64 65 IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq); 73 66 74 67 virtual ~IsoHandler(); … … 118 111 // not RT safe 119 112 // the isohandlermanager is responsible for calling this! 120 void updateCycleCounter(); 121 113 bool updateCycleCounter(); 114 float getTicksPerUsec() {return m_ticks_per_usec;}; 115 116 // register a master timing source 117 bool setSyncMaster(FreebobUtil::TimeSource *t); 118 122 119 protected: 123 120 raw1394handle_t m_handle; … … 127 124 unsigned int m_max_packet_size; 128 125 int m_irq_interval; 129 unsigned int m_cyclecounter; 130 126 127 unsigned int m_cyclecounter_ticks; 128 freebob_microsecs_t m_lastmeas_usecs; 129 float m_ticks_per_usec; 130 float m_ticks_per_usec_dll_err2; 131 131 132 int m_packetcount; 132 133 int m_dropped; … … 134 135 IsoStream *m_Client; 135 136 136 virtual int handleBusReset(unsigned int generation) = 0; 137 FreebobUtil::TimeSource *m_TimeSource; 138 139 virtual int handleBusReset(unsigned int generation); 140 137 141 138 142 DECLARE_DEBUG_MODULE; … … 141 145 static int busreset_handler(raw1394handle_t handle, unsigned int generation); 142 146 147 void initCycleCounter(); 148 149 // implement the TimeSource interface 150 public: 151 freebob_microsecs_t getCurrentTime(); 152 freebob_microsecs_t getCurrentTimeAsUsecs(); 153 private: 154 // to cope with wraparound 155 unsigned int m_TimeSource_LastSecs; 156 unsigned int m_TimeSource_NbCycleWraps; 143 157 144 158 }; … … 167 181 bool prepare(); 168 182 183 protected: 184 int handleBusReset(unsigned int generation); 185 169 186 private: 170 int handleBusReset(unsigned int generation);171 172 187 static enum raw1394_iso_disposition 173 188 iso_receive_handler(raw1394handle_t handle, unsigned char *data, … … 212 227 bool prepare(); 213 228 229 protected: 230 int handleBusReset(unsigned int generation); 231 214 232 private: 215 216 int handleBusReset(unsigned int generation);217 218 233 static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle, 219 234 unsigned char *data, unsigned int *length, trunk/libfreebob/src/libstreaming/IsoHandlerManager.cpp
r341 r360 62 62 { 63 63 updateCycleCounters(); 64 usleep(USLEEP_AFTER_UPDATE); 65 64 66 return true; 65 67 } … … 110 112 ++it ) 111 113 { 112 (*it)->updateCycleCounter(); 114 int cnt=0; 115 while (!(*it)->updateCycleCounter() && (cnt++ < MAX_UPDATE_TRIES)) { 116 usleep(USLEEP_AFTER_UPDATE_FAILURE); 117 } 113 118 } 119 114 120 } 115 121 … … 528 534 ++it ) 529 535 { 530 debugOutputShort( DEBUG_LEVEL_NORMAL, " Stream%d (%p)\n",i++,*it);536 debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it); 531 537 532 538 (*it)->dumpInfo(); trunk/libfreebob/src/libstreaming/IsoHandlerManager.h
r341 r360 36 36 37 37 #include <vector> 38 39 #define USLEEP_AFTER_UPDATE_FAILURE 10 40 #define USLEEP_AFTER_UPDATE 100 41 #define MAX_UPDATE_TRIES 10 38 42 39 43 namespace FreebobStreaming … … 92 96 void enablePolling(IsoStream *); ///< enables polling on a stream 93 97 94 p rotected:98 public: 95 99 96 100 … … 101 105 // iterate all handlers 102 106 bool iterate(); 103 107 private: 104 108 // updates the cycle counter caches of all handlers 105 109 void updateCycleCounters(); trunk/libfreebob/src/libstreaming/StreamProcessorManager.cpp
r341 r360 151 151 152 152 // the tread that runs the packet iterators 153 m_streamingThread=new FreebobUtil::PosixThread(this, m_thread_realtime, m_thread_priority+5, PTHREAD_CANCEL_DEFERRED); 153 m_streamingThread=new FreebobUtil::PosixThread(this, 154 m_thread_realtime, m_thread_priority+5, 155 PTHREAD_CANCEL_DEFERRED); 156 154 157 if(!m_streamingThread) { 155 158 debugFatal("Could not create streaming thread\n"); … … 168 171 // the tread that keeps the handler's cycle counters up to date 169 172 // NOTE: is lower priority nescessary? it can block 170 m_isoManagerThread=new FreebobUtil::PosixThread(m_isoManager, m_thread_realtime, m_thread_priority+6, PTHREAD_CANCEL_DEFERRED); 173 // m_isoManagerThread=new FreebobUtil::PosixThread(m_isoManager, m_thread_realtime, m_thread_priority+6, PTHREAD_CANCEL_DEFERRED); 174 175 // now that we are using a DLL, we don't need to run this at RT priority 176 // it only serves to cope with drift 177 // however, in order to make the DLL fast enough, we have to increase 178 // its bandwidth, making it more sensitive to deviations. These deviations 179 // are mostly determined by the time difference between reading the cycle 180 // time register and the local cpu clock. 181 182 m_isoManagerThread=new FreebobUtil::PosixThread( 183 m_isoManager, 184 m_thread_realtime, m_thread_priority+6, 185 PTHREAD_CANCEL_DEFERRED); 186 171 187 if(!m_isoManagerThread) { 172 188 debugFatal("Could not create iso manager thread\n"); … … 218 234 219 235 } 236 237 // if there are no stream processors registered, 238 // fail 239 if (m_ReceiveProcessors.size() + m_TransmitProcessors.size() == 0) { 240 debugFatal("No stream processors registered, can't do anything usefull\n"); 241 return false; 242 } 220 243 221 244 return true; trunk/libfreebob/src/Makefile.am
r358 r360 24 24 25 25 lib_LTLIBRARIES = libfreebob.la 26 27 libfreebob_la_LIBADD = -lrt 28 26 29 noinst_HEADERS = \ 27 30 configrom.h \ … … 97 100 debugmodule/debugmodule.h \ 98 101 debugmodule/debugmodule.cpp \ 99 libstreaming/cip.c \ 100 libstreaming/freebob_streaming.cpp \ 101 libstreaming/IsoHandler.cpp \ 102 libstreaming/IsoHandlerManager.cpp \ 103 libstreaming/IsoStream.cpp \ 104 libstreaming/PacketBuffer.cpp \ 105 libstreaming/PortManager.cpp \ 106 libstreaming/Port.cpp \ 107 libstreaming/StreamProcessor.cpp \ 108 libstreaming/StreamProcessorManager.cpp \ 109 libstreaming/AmdtpPortInfo.cpp \ 110 libstreaming/AmdtpPort.cpp \ 111 libstreaming/AmdtpStreamProcessor.cpp \ 112 libstreaming/ringbuffer.c \ 113 libstreaming/streamstatistics.cpp \ 114 libstreaming/MotuStreamProcessor.cpp \ 115 libstreaming/MotuPort.cpp \ 116 libstreaming/MotuPortInfo.cpp \ 117 libutil/DelayLockedLoop.h \ 118 libutil/Atomic.h \ 119 libutil/PosixThread.h \ 120 libutil/Thread.h \ 121 libutil/DelayLockedLoop.cpp \ 122 libutil/PosixThread.cpp 102 libstreaming/cip.c \ 103 libstreaming/cyclecounter.h \ 104 libstreaming/freebob_streaming.cpp \ 105 libstreaming/IsoHandler.cpp \ 106 libstreaming/IsoHandlerManager.cpp \ 107 libstreaming/IsoStream.cpp \ 108 libstreaming/PacketBuffer.cpp \ 109 libstreaming/PortManager.cpp \ 110 libstreaming/Port.cpp \ 111 libstreaming/StreamProcessor.cpp \ 112 libstreaming/StreamProcessorManager.cpp \ 113 libstreaming/AmdtpPortInfo.cpp \ 114 libstreaming/AmdtpPort.cpp \ 115 libstreaming/AmdtpStreamProcessor.cpp \ 116 libstreaming/ringbuffer.c \ 117 libstreaming/streamstatistics.cpp \ 118 libstreaming/MotuStreamProcessor.cpp \ 119 libstreaming/MotuPort.cpp \ 120 libstreaming/MotuPortInfo.cpp \ 121 libutil/DelayLockedLoop.h \ 122 libutil/Atomic.h \ 123 libutil/PosixThread.h \ 124 libutil/Thread.h \ 125 libutil/DelayLockedLoop.cpp \ 126 libutil/PosixThread.cpp \ 127 libutil/Time.c \ 128 libutil/Time.h \ 129 libutil/TimeSource.cpp \ 130 libutil/TimeSource.h \ 131 libutil/SystemTimeSource.cpp \ 132 libutil/SystemTimeSource.h \ 133 libutil/cycles.h 123 134 124 135 libfreebob_la_LDFLAGS = \ 125 136 -version-info $(LT_VERSION) $(LIBRAW1394_LIBS) \ 126 137 $(LIBIEC61883_LIBS) $(LIBAVC1394_LIBS) \ 127 $(LIBXML_LIBS) $(LIBXMLCPP_LIBS) -lpthread 138 $(LIBXML_LIBS) $(LIBXMLCPP_LIBS) -lpthread -lrt 128 139 129 140 nobase_dist_pkgdata_DATA = \ … … 141 152 $(LIBIEC61883_LIBS) \ 142 153 $(LIBAVC1394_LIBS) \ 143 154 -lpthread 144 155 145 156 freebob_sync_SOURCES = \ … … 150 161 $(LIBIEC61883_LIBS) \ 151 162 $(LIBAVC1394_LIBS) \ 152 163 -lpthread 153 164 154 noinst_PROGRAMS = test-dll test-debugmodule 165 noinst_PROGRAMS = test-dll test-debugmodule bebob_unittests 155 166 156 167 test_dll_SOURCES = libutil/test-dll.cpp … … 160 171 test_debugmodule_LDADD = libfreebob.la 161 172 162 noinst_PROGRAMS = bebob_unittests163 164 173 bebob_unittests_SOURCES = bebob/bebob_unittests.cpp 165 174 bebob_unittests_LDADD = $(top_builddir)/src/libfreebob.la \ 166 175 $(LIBXMLCPP_LIBS) $(LIBAVC1394_LIBS) $(LIBIEC61883_LIBS) 176 trunk/libfreebob/support/jack/freebob_driver.c
r312 r360 196 196 } 197 197 198 static int 198 static int 199 199 freebob_driver_detach (freebob_driver_t *driver) 200 200 { … … 449 449 float delayed_usecs=0.0; 450 450 451 jack_nframes_t nframes = freebob_driver_wait (driver, -1, &wait_status,452 451 jack_nframes_t nframes = freebob_driver_wait (driver, -1, 452 &wait_status, &delayed_usecs); 453 453 454 454 if ((wait_status < 0)) { trunk/libfreebob/tests/Makefile.am
r336 r360 16 16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 17 18 SUBDIRS = streaming18 # SUBDIRS = streaming 19 19 20 20 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src $(LIBXML_CFLAGS) \ … … 22 22 23 23 noinst_PROGRAMS = test-freebob test-extplugcmd test-fw410 freebob-server \ 24 test-volume test-mixer 24 test-volume test-mixer test-cyclecounter test-sytmonitor 25 25 26 noinst_HEADERS = 26 27 … … 51 52 #TESTS_ENVIRONMENT 52 53 TEST = test-freebob 54 55 test_cyclecounter_LDADD = $(top_builddir)/src/libfreebob.la $(LIBIEC61883_LIBS) \ 56 $(LIBRAW1394_LIBS) $(LIBAVC1394_LIBS) 57 test_cyclecounter_SOURCES = test-cyclecounter.cpp 58 59 test_sytmonitor_LDADD = $(top_builddir)/src/libfreebob.la $(LIBIEC61883_LIBS) \ 60 $(LIBRAW1394_LIBS) $(LIBAVC1394_LIBS) 61 test_sytmonitor_SOURCES = test-sytmonitor.cpp SytMonitor.cpp \ 62 SytMonitor.h trunk/libfreebob/tests/streaming/test-isohandling.cpp
r250 r360 27 27 28 28 #include <signal.h> 29 #include " debugmodule/debugmodule.h"29 #include "src/debugmodule/debugmodule.h" 30 30 31 31 #include <netinet/in.h> 32 32 33 #include " IsoHandler.h"34 #include " IsoStream.h"35 #include " StreamProcessorManager.h"36 #include " AmdtpStreamProcessor.h"37 #include " IsoHandlerManager.h"38 #include " PosixThread.h"39 #include " AmdtpPort.h"33 #include "src/libstreaming/IsoHandler.h" 34 #include "src/libstreaming/IsoStream.h" 35 #include "src/libstreaming/StreamProcessorManager.h" 36 #include "src/libstreaming/AmdtpStreamProcessor.h" 37 #include "src/libstreaming/IsoHandlerManager.h" 38 #include "src/libutil/PosixThread.h" 39 #include "src/libstreaming/AmdtpPort.h" 40 40 41 41 using namespace FreebobStreaming;