Changeset 383
- Timestamp:
- 01/28/07 09:36:11 (16 years ago)
- Files:
-
- branches/streaming-rework/src/debugmodule/debugmodule.cpp (modified) (2 diffs)
- branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp (modified) (13 diffs)
- branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.h (modified) (4 diffs)
- branches/streaming-rework/src/libstreaming/cycletimer.h (moved) (moved from branches/streaming-rework/src/libstreaming/cyclecounter.h)
- branches/streaming-rework/src/libstreaming/freebob_streaming.cpp (modified) (7 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandler.cpp (modified) (22 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandler.h (modified) (5 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp (modified) (8 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandlerManager.h (modified) (3 diffs)
- branches/streaming-rework/src/libstreaming/IsoStream.cpp (modified) (2 diffs)
- branches/streaming-rework/src/libstreaming/IsoStream.h (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/MotuStreamProcessor.cpp (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/StreamProcessor.cpp (modified) (3 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessor.h (modified) (3 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp (modified) (6 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessorManager.h (modified) (2 diffs)
- branches/streaming-rework/src/libutil/TimeSource.h (modified) (1 diff)
- branches/streaming-rework/src/Makefile.am (modified) (5 diffs)
- branches/streaming-rework/tests/test-cycletimer.cpp (moved) (moved from branches/streaming-rework/tests/test-cyclecounter.cpp)
- branches/streaming-rework/tests/test-sytmonitor.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/streaming-rework/src/debugmodule/debugmodule.cpp
r377 r383 213 213 DebugModuleManager::registerModule( DebugModule& debugModule ) 214 214 { 215 m_debugModules.push_back( &debugModule );215 m_debugModules.push_back( &debugModule ); 216 216 return true; 217 217 } … … 229 229 } 230 230 } 231 231 232 232 cerr << "DebugModuleManager::unregisterModule: Could not unregister " 233 233 << "DebugModule (" << debugModule.getName() << ")" << endl; branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp
r360 r383 94 94 int cycle, unsigned int dropped, unsigned int max_length) { 95 95 96 97 98 96 struct iec61883_packet *packet = (struct iec61883_packet *) data; 97 unsigned int nevents=0; 98 99 99 packet->eoh0 = 0; 100 100 … … 118 118 packet->fmt = IEC61883_FMT_AMDTP; 119 119 120 121 122 123 124 125 126 127 128 120 // signal that we are running (a transmit stream is always 'runnable') 121 m_running=true; 122 123 // don't process the stream when it is not enabled. 124 // however, we do have to generate (semi) valid packets 125 // that means that we'll send NODATA packets FIXME: check!! 126 if(m_disabled) { 127 // no-data packets have syt=0xFFFF 128 // and have the usual amount of events as dummy data 129 129 packet->fdf = IEC61883_FDF_NODATA; 130 130 packet->syt = 0xffff; … … 133 133 m_dbc += m_syt_interval; 134 134 135 136 137 138 139 140 135 *length = 2*sizeof(quadlet_t) + m_syt_interval * m_dimension * sizeof(quadlet_t); 136 *tag = IEC61883_TAG_WITH_CIP; 137 *sy = 0; 138 139 return RAW1394_ISO_DEFER; 140 } 141 141 142 142 packet->fdf = m_fdf; … … 447 447 448 448 // reset the statistics 449 449 m_PeriodStat.reset(); 450 450 m_PacketStat.reset(); 451 451 m_WakeupStat.reset(); … … 1048 1048 1049 1049 unsigned int syt_timestamp=ntohs(packet->syt); 1050 1050 // reconstruct the top part of the timestamp using the current cycle number 1051 1051 unsigned int now_cycle_masked=cycle & 0xF; 1052 1052 unsigned int syt_cycle=CYCLE_COUNTER_GET_CYCLES(syt_timestamp); … … 1090 1090 measured_difference+=TICKS_PER_SECOND; 1091 1091 } 1092 1092 1093 1093 // implement a 1st order DLL to estimate the framerate 1094 1094 // this is the number of ticks between two samples … … 1115 1115 1116 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,1117 cycle,now_cycle_masked,delta_cycles, 1118 1118 CYCLE_COUNTER_TO_TICKS(m_last_timestamp), 1119 1119 CYCLE_COUNTER_GET_CYCLES(m_last_timestamp), … … 1121 1121 ntohs(packet->syt),m_last_timestamp&0xFFFF, dropped 1122 1122 ); 1123 1123 1124 1124 #ifdef DEBUG 1125 1125 if(m_last_timestamp<m_last_timestamp2) { … … 1134 1134 } 1135 1135 #endif 1136 1136 1137 1137 // don't process the stream samples when it is not enabled. 1138 1138 if(m_disabled) { … … 1175 1175 } 1176 1176 #endif 1177 1177 1178 1178 // update the frame counter 1179 1179 incrementFrameCounter(nevents); … … 1182 1182 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"defer!\n"); 1183 1183 } 1184 1184 1185 1185 } else { 1186 1186 // discard packet … … 1419 1419 bool AmdtpReceiveStreamProcessor::reset() { 1420 1420 1421 1422 1423 1424 1425 1421 debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n"); 1422 1423 // reset the event buffer, discard all content 1424 freebob_ringbuffer_reset(m_event_buffer); 1425 1426 1426 // reset the last timestamp 1427 1427 m_last_timestamp=0; 1428 1428 1429 1429 m_PeriodStat.reset(); 1430 1430 m_PacketStat.reset(); 1431 1431 m_WakeupStat.reset(); … … 1440 1440 m_last_timestamp2=0; 1441 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1442 m_one_period_passed=false; 1443 1444 // reset all non-device specific stuff 1445 // i.e. the iso stream and the associated ports 1446 if(!ReceiveStreamProcessor::reset()) { 1447 debugFatal("Could not do base class reset\n"); 1448 return false; 1449 } 1450 return true; 1451 1451 } 1452 1452 branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.h
r360 r383 76 76 friend class AmdtpReceiveStreamProcessor; 77 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 78 AmdtpTransmitStreamProcessor(int port, int framerate, int dimension); 79 80 virtual ~AmdtpTransmitStreamProcessor(); 81 82 enum raw1394_iso_disposition 83 getPacket(unsigned char *data, unsigned int *length, 84 unsigned char *tag, unsigned char *sy, 85 int cycle, unsigned int dropped, unsigned int max_length); 86 87 bool init(); 88 bool reset(); 89 bool prepare(); 90 bool transfer(); 91 virtual void setVerboseLevel(int l); 92 93 bool isOnePeriodReady(); 94 94 95 95 // We have 1 period of samples = m_period … … 100 100 // however, if we only count the number of used packets 101 101 // it is m_period / m_syt_interval 102 103 104 102 unsigned int getPacketsPerPeriod() {return (m_period)/m_syt_interval;}; 103 104 unsigned int getMaxPacketSize() {return 4 * (2 + m_syt_interval * m_dimension);}; 105 105 106 106 // FIXME: do this the proper way! … … 116 116 protected: 117 117 118 119 120 121 122 123 124 125 126 118 struct iec61883_cip m_cip_status; 119 120 freebob_ringbuffer_t * m_event_buffer; 121 char* m_cluster_buffer; 122 int m_dimension; 123 unsigned int m_syt_interval; 124 125 int m_fdf; 126 127 127 bool prefill(); 128 128 129 130 131 132 133 134 135 136 137 138 139 140 141 129 bool transferSilence(unsigned int size); 130 131 int transmitBlock(char *data, unsigned int nevents, 132 unsigned int offset); 133 134 bool encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 135 int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 136 unsigned int offset, unsigned int nevents); 137 138 int transmitSilenceBlock(char *data, unsigned int nevents, 139 unsigned int offset); 140 int encodeSilencePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 141 unsigned int offset, unsigned int nevents); 142 142 143 143 unsigned long m_last_timestamp; … … 201 201 protected: 202 202 203 204 205 206 207 208 209 210 211 203 int receiveBlock(char *data, unsigned int nevents, unsigned int offset); 204 bool decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 205 206 int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents); 207 208 freebob_ringbuffer_t * m_event_buffer; 209 char* m_cluster_buffer; 210 int m_dimension; 211 unsigned int m_syt_interval; 212 212 213 213 unsigned int m_last_timestamp; branches/streaming-rework/src/libstreaming/freebob_streaming.cpp
r360 r383 2 2 3 3 /* 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 4 * FreeBob Streaming API 5 * FreeBob = Firewire (pro-)audio for linux 6 * 7 * http://freebob.sf.net 8 * 9 * Copyright (C) 2005,2006 Pieter Palmers <pieterpalmers@users.sourceforge.net> 10 * 11 * This program is free software {} you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation {} either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY {} without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program {} if not, write to the Free Software 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 25 * 26 * 27 */ 28 28 29 29 /* freebob_streaming.c 30 31 32 33 30 * 31 * Implementation of the FreeBob Streaming API 32 * 33 */ 34 34 35 35 #include "libfreebob/freebob_streaming.h" … … 52 52 53 53 /** 54 55 54 * Device structure 55 */ 56 56 57 57 DECLARE_GLOBAL_DEBUG_MODULE; … … 61 61 struct _freebob_device 62 62 { 63 64 65 66 67 63 DeviceManager * m_deviceManager; 64 StreamProcessorManager *processorManager; 65 66 freebob_options_t options; 67 freebob_device_info_t device_info; 68 68 }; 69 69 70 70 freebob_device_t *freebob_streaming_init (freebob_device_info_t *device_info, freebob_options_t options) { 71 unsigned int i=0; 72 73 struct _freebob_device *dev = new struct _freebob_device; 74 75 debugFatal("%s built %s %s\n", freebob_get_version(), __DATE__, __TIME__); 76 77 if(!dev) { 78 debugFatal( "Could not allocate streaming device\n" ); 79 return 0; 80 } 81 82 memcpy((void *)&dev->options, (void *)&options, sizeof(dev->options)); 83 memcpy((void *)&dev->device_info, (void *)device_info, sizeof(dev->device_info)); 84 85 dev->m_deviceManager = new DeviceManager(); 86 if ( !dev->m_deviceManager ) { 87 debugFatal( "Could not allocate device manager\n" ); 88 delete dev; 89 return 0; 90 } 91 if ( !dev->m_deviceManager->initialize( dev->options.port ) ) { 92 debugFatal( "Could not initialize device manager\n" ); 93 delete dev->m_deviceManager; 94 delete dev; 95 return 0; 96 } 97 98 // create a processor manager to manage the actual stream 99 // processors 100 dev->processorManager = new StreamProcessorManager(dev->options.period_size,dev->options.nb_buffers); 101 if(!dev->processorManager) { 102 debugFatal("Could not create StreamProcessorManager\n"); 103 delete dev->m_deviceManager; 104 delete dev; 105 return 0; 106 } 107 108 dev->processorManager->setThreadParameters(dev->options.realtime, dev->options.packetizer_priority); 109 110 dev->processorManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 111 if(!dev->processorManager->init()) { 112 debugFatal("Could not init StreamProcessorManager\n"); 113 delete dev->processorManager; 114 delete dev->m_deviceManager; 115 delete dev; 116 return 0; 117 } 118 119 // discover the devices on the bus 120 if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 121 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not discover devices\n"); 122 delete dev->processorManager; 123 delete dev->m_deviceManager; 124 delete dev; 125 return 0; 126 } 127 128 // iterate over the found devices 129 // add the stream processors of the devices to the managers 130 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 131 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 132 assert(device); 133 134 // Set the device's sampling rate to that requested 135 // FIXME: does this really belong here? If so we need to handle errors. 136 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 137 // try again: 138 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 71 unsigned int i=0; 72 73 struct _freebob_device *dev = new struct _freebob_device; 74 75 debugFatal("%s built %s %s\n", freebob_get_version(), __DATE__, __TIME__); 76 77 if(!dev) { 78 debugFatal( "Could not allocate streaming device\n" ); 79 return 0; 80 } 81 82 memcpy((void *)&dev->options, (void *)&options, sizeof(dev->options)); 83 memcpy((void *)&dev->device_info, (void *)device_info, sizeof(dev->device_info)); 84 85 dev->m_deviceManager = new DeviceManager(); 86 if ( !dev->m_deviceManager ) { 87 debugFatal( "Could not allocate device manager\n" ); 88 delete dev; 89 return 0; 90 } 91 if ( !dev->m_deviceManager->initialize( dev->options.port ) ) { 92 debugFatal( "Could not initialize device manager\n" ); 93 delete dev->m_deviceManager; 94 delete dev; 95 return 0; 96 } 97 98 // create a processor manager to manage the actual stream 99 // processors 100 dev->processorManager = new StreamProcessorManager(dev->options.period_size,dev->options.nb_buffers); 101 if(!dev->processorManager) { 102 debugFatal("Could not create StreamProcessorManager\n"); 103 delete dev->m_deviceManager; 104 delete dev; 105 return 0; 106 } 107 108 dev->processorManager->setThreadParameters(dev->options.realtime, dev->options.packetizer_priority); 109 110 dev->processorManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 111 if(!dev->processorManager->init()) { 112 debugFatal("Could not init StreamProcessorManager\n"); 139 113 delete dev->processorManager; 140 114 delete dev->m_deviceManager; 141 115 delete dev; 142 debugFatal("Could not set sampling frequency to %d\n",dev->options.sample_rate); 143 return 0; 144 } 145 } 146 147 // prepare the device 148 device->prepare(); 149 150 int j=0; 151 for(j=0; j<device->getStreamCount();j++) { 152 StreamProcessor *streamproc=device->getStreamProcessorByIndex(j); 153 debugOutput(DEBUG_LEVEL_VERBOSE, "Registering stream processor %d of device %d with processormanager\n",j,i); 154 if (!dev->processorManager->registerProcessor(streamproc)) { 155 debugWarning("Could not register stream processor (%p) with the Processor manager\n",streamproc); 156 } 157 } 158 } 159 160 // we are ready! 116 return 0; 117 } 118 119 // discover the devices on the bus 120 if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 121 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not discover devices\n"); 122 delete dev->processorManager; 123 delete dev->m_deviceManager; 124 delete dev; 125 return 0; 126 } 127 128 // iterate over the found devices 129 // add the stream processors of the devices to the managers 130 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 131 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 132 assert(device); 133 134 // Set the device's sampling rate to that requested 135 // FIXME: does this really belong here? If so we need to handle errors. 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 } 146 147 // prepare the device 148 device->prepare(); 149 150 int j=0; 151 for(j=0; j<device->getStreamCount();j++) { 152 StreamProcessor *streamproc=device->getStreamProcessorByIndex(j); 153 debugOutput(DEBUG_LEVEL_VERBOSE, "Registering stream processor %d of device %d with processormanager\n",j,i); 154 if (!dev->processorManager->registerProcessor(streamproc)) { 155 debugWarning("Could not register stream processor (%p) with the Processor manager\n",streamproc); 156 } 157 } 158 } 159 160 // we are ready! 161 161 162 163 162 debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n\n"); 163 return dev; 164 164 165 165 } 166 166 167 167 int freebob_streaming_prepare(freebob_device_t *dev) { 168 debugOutput(DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 168 debugOutput(DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 169 170 if (!dev->processorManager->prepare()) { 171 debugFatal("Could not prepare streaming...\n"); 172 return false; 173 } 174 175 return true; 176 } 177 178 void freebob_streaming_finish(freebob_device_t *dev) { 179 180 assert(dev); 181 182 delete dev->processorManager; 183 delete dev->m_deviceManager; 184 delete dev; 185 186 return; 187 } 188 189 int freebob_streaming_start(freebob_device_t *dev) { 190 unsigned int i=0; 191 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Start -------------\n"); 192 169 193 170 if (!dev->processorManager->prepare()) { 171 debugFatal("Could not prepare streaming...\n"); 172 return false; 173 } 174 175 return true; 176 } 177 178 void freebob_streaming_finish(freebob_device_t *dev) { 179 180 assert(dev); 181 182 delete dev->processorManager; 183 delete dev->m_deviceManager; 184 delete dev; 185 186 return; 187 } 188 189 int freebob_streaming_start(freebob_device_t *dev) { 190 unsigned int i=0; 191 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Start -------------\n"); 192 193 194 // create the connections for all devices 195 // iterate over the found devices 196 // add the stream processors of the devices to the managers 197 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 198 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 199 assert(device); 200 201 int j=0; 202 for(j=0; j<device->getStreamCount();j++) { 203 debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %d\n",j,i); 204 // start the stream 205 device->startStreamByIndex(j); 206 } 207 } 194 // create the connections for all devices 195 // iterate over the found devices 196 // add the stream processors of the devices to the managers 197 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 198 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 199 assert(device); 200 201 int j=0; 202 for(j=0; j<device->getStreamCount();j++) { 203 debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %d\n",j,i); 204 // start the stream 205 device->startStreamByIndex(j); 206 } 207 } 208 208 209 209 dev->processorManager->start(); 210 210 211 211 return 0; 212 212 } 213 213 214 214 int freebob_streaming_stop(freebob_device_t *dev) { 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 215 unsigned int i; 216 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Stop -------------\n"); 217 218 dev->processorManager->stop(); 219 220 // create the connections for all devices 221 // iterate over the found devices 222 // add the stream processors of the devices to the managers 223 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 224 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 225 assert(device); 226 227 228 int j=0; 229 for(j=0; j<device->getStreamCount();j++) { 230 debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %d\n",j,i); 231 // stop the stream 232 device->stopStreamByIndex(j); 233 } 234 } 235 236 return 0; 237 237 } 238 238 239 239 int freebob_streaming_reset(freebob_device_t *dev) { 240 240 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Reset -------------\n"); 241 241 242 242 // dev->processorManager->reset(); 243 243 244 244 return 0; 245 245 } 246 246 247 247 int freebob_streaming_wait(freebob_device_t *dev) { 248 249 250 251 252 253 254 255 256 257 258 248 static int periods=0; 249 static int periods_print=0; 250 static int xruns=0; 251 252 periods++; 253 if(periods>periods_print) { 254 debugOutput(DEBUG_LEVEL_VERBOSE, "\n"); 255 debugOutput(DEBUG_LEVEL_VERBOSE, "============================================\n"); 256 debugOutput(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); 257 debugOutput(DEBUG_LEVEL_VERBOSE, "============================================\n"); 258 dev->processorManager->dumpInfo(); 259 259 // debugOutput(DEBUG_LEVEL_VERBOSE, "--------------------------------------------\n"); 260 260 /* quadlet_t *addr=(quadlet_t*)(dev->processorManager->getPortByIndex(0, Port::E_Capture)->getBufferAddress()); 261 262 263 264 265 266 267 268 269 270 271 272 273 274 261 if (addr) hexDumpQuadlets(addr,10);*/ 262 debugOutput(DEBUG_LEVEL_VERBOSE, "\n"); 263 periods_print+=100; 264 } 265 if(dev->processorManager->waitForPeriod()) { 266 return dev->options.period_size; 267 } else { 268 debugWarning("XRUN detected\n"); 269 // do xrun recovery 270 271 dev->processorManager->handleXrun(); 272 xruns++; 273 return -1; 274 } 275 275 } 276 276 277 277 int freebob_streaming_transfer_capture_buffers(freebob_device_t *dev) { 278 278 return dev->processorManager->transfer(StreamProcessor::E_Receive); 279 279 } 280 280 281 281 int freebob_streaming_transfer_playback_buffers(freebob_device_t *dev) { 282 282 return dev->processorManager->transfer(StreamProcessor::E_Transmit); 283 283 } 284 284 285 285 int freebob_streaming_transfer_buffers(freebob_device_t *dev) { 286 286 return dev->processorManager->transfer(); 287 287 } 288 288 … … 290 290 int freebob_streaming_write(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) { 291 291 // debugFatal("Not implemented\n"); 292 293 294 295 296 297 292 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 293 // use an assert here performancewise, 294 // it should already have failed before, if not correct 295 assert(p); 296 297 return p->writeEvents((void *)buffer, nsamples); 298 298 } 299 299 300 300 int freebob_streaming_read(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) { 301 302 303 304 305 306 301 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 302 // use an assert here performancewise, 303 // it should already have failed before, if not correct 304 assert(p); 305 306 return p->readEvents((void *)buffer, nsamples); 307 307 } 308 308 309 309 pthread_t freebob_streaming_get_packetizer_thread(freebob_device_t *dev) { 310 310 // debugFatal("Not implemented\n"); 311 311 return 0; 312 312 } 313 313 314 314 315 315 int freebob_streaming_get_nb_capture_streams(freebob_device_t *dev) { 316 316 return dev->processorManager->getPortCount(Port::E_Capture); 317 317 } 318 318 319 319 int freebob_streaming_get_nb_playback_streams(freebob_device_t *dev) { 320 320 return dev->processorManager->getPortCount(Port::E_Playback); 321 321 } 322 322 323 323 int freebob_streaming_get_capture_stream_name(freebob_device_t *dev, int i, char* buffer, size_t buffersize) { 324 325 326 327 328 329 330 331 332 333 334 324 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 325 if(!p) { 326 debugWarning("Could not get capture port at index %d\n",i); 327 return -1; 328 } 329 330 std::string name=p->getName(); 331 if (!strncpy(buffer, name.c_str(), buffersize)) { 332 debugWarning("Could not copy name\n"); 333 return -1; 334 } else return 0; 335 335 } 336 336 337 337 int freebob_streaming_get_playback_stream_name(freebob_device_t *dev, int i, char* buffer, size_t buffersize) { 338 339 340 341 342 343 344 345 346 347 348 349 338 339 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 340 if(!p) { 341 debugWarning("Could not get playback port at index %d\n",i); 342 return -1; 343 } 344 345 std::string name=p->getName(); 346 if (!strncpy(buffer, name.c_str(), buffersize)) { 347 debugWarning("Could not copy name\n"); 348 return -1; 349 } else return 0; 350 350 } 351 351 352 352 freebob_streaming_stream_type freebob_streaming_get_capture_stream_type(freebob_device_t *dev, int i) { 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 353 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 354 if(!p) { 355 debugWarning("Could not get capture port at index %d\n",i); 356 return freebob_stream_type_invalid; 357 } 358 switch(p->getPortType()) { 359 case Port::E_Audio: 360 return freebob_stream_type_audio; 361 case Port::E_Midi: 362 return freebob_stream_type_midi; 363 case Port::E_Control: 364 return freebob_stream_type_control; 365 default: 366 return freebob_stream_type_unknown; 367 } 368 368 } 369 369 370 370 freebob_streaming_stream_type freebob_streaming_get_playback_stream_type(freebob_device_t *dev, int i) { 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 371 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 372 if(!p) { 373 debugWarning("Could not get playback port at index %d\n",i); 374 return freebob_stream_type_invalid; 375 } 376 switch(p->getPortType()) { 377 case Port::E_Audio: 378 return freebob_stream_type_audio; 379 case Port::E_Midi: 380 return freebob_stream_type_midi; 381 case Port::E_Control: 382 return freebob_stream_type_control; 383 default: 384 return freebob_stream_type_unknown; 385 } 386 386 } 387 387 … … 389 389 freebob_streaming_buffer_type t, enum Port::E_Direction direction) { 390 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 391 Port *p=dev->processorManager->getPortByIndex(i, direction); 392 if(!p) { 393 debugWarning("Could not get %s port at index %d\n", 394 (direction==Port::E_Playback?"Playback":"Capture"),i); 395 return -1; 396 } 397 398 switch(t) { 399 case freebob_buffer_type_int24: 400 if (!p->setDataType(Port::E_Int24)) { 401 debugWarning("%s: Could not set data type to Int24\n",p->getName().c_str()); 402 return -1; 403 } 404 if (!p->setBufferType(Port::E_PointerBuffer)) { 405 debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 406 return -1; 407 } 408 break; 409 case freebob_buffer_type_float: 410 if (!p->setDataType(Port::E_Float)) { 411 debugWarning("%s: Could not set data type to Float\n",p->getName().c_str()); 412 return -1; 413 } 414 if (!p->setBufferType(Port::E_PointerBuffer)) { 415 debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 416 return -1; 417 } 418 break; 419 case freebob_buffer_type_midi: 420 if (!p->setDataType(Port::E_MidiEvent)) { 421 debugWarning("%s: Could not set data type to MidiEvent\n",p->getName().c_str()); 422 return -1; 423 } 424 if (!p->setBufferType(Port::E_RingBuffer)) { 425 debugWarning("%s: Could not set buffer type to Ringbuffer\n",p->getName().c_str()); 426 return -1; 427 } 428 break; 429 default: 430 debugWarning("%s: Unsupported buffer type\n",p->getName().c_str()); 431 return -1; 432 } 433 433 return 0; 434 434 … … 445 445 int freebob_streaming_stream_onoff(freebob_device_t *dev, int i, 446 446 int on, enum Port::E_Direction direction) { 447 448 449 450 451 452 453 454 455 456 457 458 447 Port *p=dev->processorManager->getPortByIndex(i, direction); 448 if(!p) { 449 debugWarning("Could not get %s port at index %d\n", 450 (direction==Port::E_Playback?"Playback":"Capture"),i); 451 return -1; 452 } 453 if(on) { 454 p->enable(); 455 } else { 456 p->disable(); 457 } 458 return 0; 459 459 } 460 460 … … 469 469 // TODO: the way port buffers are set in the C api doesn't satisfy me 470 470 int freebob_streaming_set_capture_stream_buffer(freebob_device_t *dev, int i, char *buff) { 471 472 473 474 475 476 477 478 479 480 471 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 472 473 // use an assert here performancewise, 474 // it should already have failed before, if not correct 475 assert(p); 476 477 p->useExternalBuffer(true); 478 p->setExternalBufferAddress((void *)buff); 479 480 return 0; 481 481 482 482 } 483 483 484 484 int freebob_streaming_set_playback_stream_buffer(freebob_device_t *dev, int i, char *buff) { 485 486 487 488 489 490 491 492 493 494 } 495 485 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 486 // use an assert here performancewise, 487 // it should already have failed before, if not correct 488 assert(p); 489 490 p->useExternalBuffer(true); 491 p->setExternalBufferAddress((void *)buff); 492 493 return 0; 494 } 495 branches/streaming-rework/src/libstreaming/IsoHandler.cpp
r360 r383 118 118 IsoHandler::~IsoHandler() { 119 119 if(m_handle) { 120 stop();120 stop(); 121 121 raw1394_destroy_handle(m_handle); 122 122 } … … 129 129 IsoHandler::init() 130 130 { 131 132 133 134 135 131 debugOutput( DEBUG_LEVEL_VERBOSE, "IsoHandler (%p) enter...\n",this); 132 133 m_handle = raw1394_new_handle_on_port( m_port ); 134 if ( !m_handle ) { 135 if ( !errno ) { 136 136 cerr << "libraw1394 not compatible" << endl; 137 137 } else { 138 138 perror( "IsoHandler::Initialize: Could not get 1394 handle" ); 139 139 cerr << "Is ieee1394 and raw1394 driver loaded?" << endl; 140 141 142 143 144 145 146 147 148 140 } 141 return false; 142 } 143 raw1394_set_userdata(m_handle, static_cast<void *>(this)); 144 145 // a second handle for utility stuff 146 m_handle_util = raw1394_new_handle_on_port( m_port ); 147 if ( !m_handle_util ) { 148 if ( !errno ) { 149 149 cerr << "libraw1394 not compatible" << endl; 150 150 } else { 151 151 perror( "IsoHandler::Initialize: Could not get 1394 handle" ); 152 152 cerr << "Is ieee1394 and raw1394 driver loaded?" << endl; 153 } 154 return false; 153 } 154 return false; 155 } 156 157 raw1394_set_userdata(m_handle_util, static_cast<void *>(this)); 158 159 if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) { 160 debugWarning("Could not enable busreset notification.\n"); 161 debugWarning(" Error message: %s\n",strerror(errno)); 155 162 } 156 163 157 raw1394_set_userdata(m_handle_util, static_cast<void *>(this)); 158 159 if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) { 160 debugWarning("Could not enable busreset notification.\n"); 161 debugWarning(" Error message: %s\n",strerror(errno)); 162 } 163 164 raw1394_set_bus_reset_handler(m_handle, busreset_handler); 164 raw1394_set_bus_reset_handler(m_handle, busreset_handler); 165 165 166 166 // initialize the local timesource … … 171 171 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 172 172 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 173 173 174 174 new_counter= ntohl(buf) & 0xFFFFFFFF; 175 175 m_TimeSource_LastSecs=CYCLE_COUNTER_GET_SECS(new_counter); … … 177 177 // update the cycle counter value for initial value 178 178 initCycleCounter(); 179 180 179 180 return true; 181 181 } 182 182 … … 185 185 { 186 186 m_TimeSource=t; 187 187 188 188 // update the cycle counter value for initial value 189 189 initCycleCounter(); 190 190 191 191 return true; 192 192 } … … 194 194 bool IsoHandler::stop() 195 195 { 196 197 raw1394_iso_stop(m_handle); 198 196 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 197 raw1394_iso_stop(m_handle); 198 return true; 199 199 } 200 200 … … 206 206 207 207 int IsoHandler::handleBusReset(unsigned int generation) { 208 209 210 211 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 212 initCycleCounter(); 213 213 214 214 return 0; 215 215 } 216 216 … … 225 225 // and the estimated tick rate 226 226 freebob_microsecs_t now=m_TimeSource->getCurrentTimeAsUsecs(); 227 227 228 228 // linear interpolation 229 229 int delta_usecs=now-m_lastmeas_usecs; 230 230 231 231 float offset=m_ticks_per_usec * ((float)delta_usecs); 232 232 233 233 unsigned int pred_ticks=m_cyclecounter_ticks+(unsigned int)offset; 234 234 235 235 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Get CC: d_usecs=%d, offset=%f, cc_ticks=%lu, pred_ticks=%lu\n", 236 236 delta_usecs, offset, m_cyclecounter_ticks,pred_ticks 237 237 ); 238 238 239 239 // if we need to wrap, do it 240 240 if (pred_ticks > TICKS_PER_SECOND * 128) { … … 247 247 bool IsoHandler::updateCycleCounter() { 248 248 quadlet_t buf=0; 249 249 250 250 freebob_microsecs_t prev_usecs=m_lastmeas_usecs; 251 251 unsigned int prev_ticks=m_cyclecounter_ticks; … … 295 295 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 296 296 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 297 297 298 298 new_counter= ntohl(buf) & 0xFFFFFFFF; 299 299 new_ticks=CYCLE_COUNTER_TO_TICKS(new_counter); 300 300 301 301 // the difference in system time 302 302 int delta_usecs=new_usecs-prev_usecs; … … 386 386 m_cyclecounter_ticks -= TICKS_PER_SECOND * 128; 387 387 } 388 388 389 389 m_lastmeas_usecs = new_usecs; 390 390 … … 446 446 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 447 447 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 448 448 449 449 new_counter= ntohl(buf) & 0xFFFFFFFF; 450 450 new_ticks=CYCLE_COUNTER_TO_TICKS(new_counter); … … 490 490 { 491 491 492 493 494 495 496 497 498 499 500 492 int channel=-1; 493 if (m_Client) channel=m_Client->getChannel(); 494 495 debugOutputShort( DEBUG_LEVEL_NORMAL, " Handler type : %s\n", 496 (this->getType()==EHT_Receive ? "Receive" : "Transmit")); 497 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : %2d, %2d\n", 498 m_port, channel); 499 debugOutputShort( DEBUG_LEVEL_NORMAL, " Packet count : %10d (%5d dropped)\n", 500 this->getPacketCount(), this->getDroppedCount()); 501 501 #ifdef DEBUG 502 502 unsigned int cc=this->getCycleCounter(); 503 503 debugOutputShort( DEBUG_LEVEL_NORMAL, " Cycle counter : %10lu (%03us, %04ucycles, %04uticks)\n", 504 505 506 507 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); 508 508 509 509 }; … … 511 511 void IsoHandler::setVerboseLevel(int l) 512 512 { 513 513 setDebugLevel(l); 514 514 } 515 515 516 516 bool IsoHandler::registerStream(IsoStream *stream) 517 517 { 518 519 520 521 522 523 524 525 526 527 528 529 530 518 assert(stream); 519 debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream); 520 521 if (m_Client) { 522 debugFatal( "Generic IsoHandlers can have only one client\n"); 523 return false; 524 } 525 526 m_Client=stream; 527 528 m_Client->setHandler(this); 529 530 return true; 531 531 532 532 } … … 534 534 bool IsoHandler::unregisterStream(IsoStream *stream) 535 535 { 536 537 538 539 540 541 542 543 544 545 546 547 536 assert(stream); 537 debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream); 538 539 if(stream != m_Client) { 540 debugFatal( "no client registered\n"); 541 return false; 542 } 543 544 m_Client->clearHandler(); 545 546 m_Client=0; 547 return true; 548 548 549 549 } … … 595 595 596 596 IsoRecvHandler::IsoRecvHandler(int port) 597 598 { 599 597 : IsoHandler(port) 598 { 599 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 600 600 } 601 601 IsoRecvHandler::IsoRecvHandler(int port, unsigned int buf_packets, 602 602 unsigned int max_packet_size, int irq) 603 604 { 605 603 : IsoHandler(port, buf_packets,max_packet_size,irq) 604 { 605 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 606 606 607 607 } … … 619 619 bool 620 620 IsoRecvHandler::init() { 621 622 623 624 625 626 621 debugOutput( DEBUG_LEVEL_VERBOSE, "init recv handler %p\n",this); 622 623 if(!(IsoHandler::init())) { 624 return false; 625 } 626 return true; 627 627 628 628 } 629 629 630 630 enum raw1394_iso_disposition IsoRecvHandler::putPacket(unsigned char *data, unsigned int length, 631 632 633 634 635 636 637 638 639 640 641 642 643 644 631 unsigned char channel, unsigned char tag, unsigned char sy, 632 unsigned int cycle, unsigned int dropped) { 633 634 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, 635 "received packet: length=%d, channel=%d, cycle=%d\n", 636 length, channel, cycle ); 637 m_packetcount++; 638 m_dropped+=dropped; 639 640 if(m_Client) { 641 return m_Client->putPacket(data, length, channel, tag, sy, cycle, dropped); 642 } 643 644 return RAW1394_ISO_OK; 645 645 } 646 646 … … 651 651 // confirmed present in libraw1394 1.2.1. 652 652 // raw1394_iso_shutdown(m_handle); 653 654 655 656 657 658 653 654 debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso receive handler (%p)\n",this); 655 debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers : %d \n",m_buf_packets); 656 debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n",m_max_packet_size); 657 debugOutput( DEBUG_LEVEL_VERBOSE, " Channel : %d \n",m_Client->getChannel()); 658 debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval : %d \n",m_irq_interval); 659 659 660 660 if(raw1394_iso_recv_init(m_handle, iso_receive_handler, 661 662 663 664 665 666 667 668 669 670 671 661 m_buf_packets, 662 m_max_packet_size, 663 m_Client->getChannel(), 664 RAW1394_DMA_BUFFERFILL, 665 m_irq_interval)) { 666 debugFatal("Could not do receive initialisation!\n" ); 667 debugFatal(" %s\n",strerror(errno)); 668 669 return false; 670 } 671 return true; 672 672 } 673 673 674 674 bool IsoRecvHandler::start(int cycle) 675 675 { 676 677 678 679 680 681 682 676 debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle); 677 678 if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) { 679 debugFatal("Could not start receive handler (%s)\n",strerror(errno)); 680 return false; 681 } 682 return true; 683 683 } 684 684 685 685 int IsoRecvHandler::handleBusReset(unsigned int generation) { 686 687 688 689 690 691 692 693 694 686 debugOutput( DEBUG_LEVEL_VERBOSE, "handle bus reset...\n"); 687 688 //TODO: implement busreset 689 690 // pass on the busreset signal 691 if(IsoHandler::handleBusReset(generation)) { 692 return -1; 693 } 694 return 0; 695 695 } 696 696 … … 698 698 699 699 IsoXmitHandler::IsoXmitHandler(int port) 700 701 { 702 700 : IsoHandler(port), m_prebuffers(0) 701 { 702 debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n"); 703 703 704 704 } 705 705 IsoXmitHandler::IsoXmitHandler(int port, unsigned int buf_packets, 706 706 unsigned int max_packet_size, int irq) 707 708 709 { 710 707 : IsoHandler(port, buf_packets, max_packet_size,irq), 708 m_speed(RAW1394_ISO_SPEED_400), m_prebuffers(0) 709 { 710 debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n"); 711 711 712 712 } … … 714 714 unsigned int max_packet_size, int irq, 715 715 enum raw1394_iso_speed speed) 716 717 718 { 719 716 : IsoHandler(port, buf_packets,max_packet_size,irq), 717 m_speed(speed), m_prebuffers(0) 718 { 719 debugOutput( DEBUG_LEVEL_VERBOSE, "IsoXmitHandler enter...\n"); 720 720 721 721 } … … 735 735 IsoXmitHandler::init() { 736 736 737 738 739 740 741 742 743 737 debugOutput( DEBUG_LEVEL_VERBOSE, "init xmit handler %p\n",this); 738 739 if(!(IsoHandler::init())) { 740 return false; 741 } 742 743 return true; 744 744 745 745 } … … 764 764 bool IsoXmitHandler::prepare() 765 765 { 766 767 766 debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso transmit handler (%p, client=%p)\n",this,m_Client); 767 768 768 // raw1394_iso_shutdown(m_handle); 769 770 771 772 773 774 775 769 debugOutput( DEBUG_LEVEL_VERBOSE, " Buffers : %d \n",m_buf_packets); 770 debugOutput( DEBUG_LEVEL_VERBOSE, " Max Packet size : %d \n",m_max_packet_size); 771 debugOutput( DEBUG_LEVEL_VERBOSE, " Channel : %d \n",m_Client->getChannel()); 772 debugOutput( DEBUG_LEVEL_VERBOSE, " Speed : %d \n",m_speed); 773 debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval : %d \n",m_irq_interval); 774 775 if(raw1394_iso_xmit_init(m_handle, 776 776 iso_transmit_handler, 777 777 m_buf_packets, 778 778 m_max_packet_size, 779 780 779 m_Client->getChannel(), 780 m_speed, 781 781 m_irq_interval)) { 782 783 784 785 786 787 782 debugFatal("Could not do xmit initialisation!\n" ); 783 784 return false; 785 } 786 787 return true; 788 788 } 789 789 790 790 bool IsoXmitHandler::start(int cycle) 791 791 { 792 793 794 795 796 797 792 debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle); 793 if(raw1394_iso_xmit_start(m_handle, cycle, m_prebuffers)) { 794 debugFatal("Could not start xmit handler (%s)\n",strerror(errno)); 795 return false; 796 } 797 return true; 798 798 } 799 799 800 800 int IsoXmitHandler::handleBusReset(unsigned int generation) { 801 802 803 804 805 806 807 808 809 801 debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 802 //TODO: implement busreset 803 804 // pass on the busreset signal 805 if(IsoHandler::handleBusReset(generation)) { 806 return -1; 807 } 808 809 return 0; 810 810 } 811 811 branches/streaming-rework/src/libstreaming/IsoHandler.h
r360 r383 52 52 class IsoHandler : public FreebobUtil::TimeSource 53 53 { 54 protected: 54 protected: 55 56 public: 55 57 56 public: 57 58 enum EHandlerType { 59 EHT_Receive, 60 EHT_Transmit 61 }; 62 63 IsoHandler(int port); 64 65 IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq); 66 67 virtual ~IsoHandler(); 68 69 virtual bool init(); 70 71 int iterate() { if(m_handle) return raw1394_loop_iterate(m_handle); else return -1; }; 72 73 void setVerboseLevel(int l); 74 75 // no setter functions, because those would require a re-init 76 unsigned int getMaxPacketSize() { return m_max_packet_size;}; 77 unsigned int getBuffersize() { return m_buf_packets;}; 78 int getWakeupInterval() { return m_irq_interval;}; 79 80 int getPacketCount() {return m_packetcount;}; 81 void resetPacketCount() {m_packetcount=0;}; 82 83 int getDroppedCount() {return m_dropped;}; 84 void resetDroppedCount() {m_dropped=0;}; 85 86 virtual enum EHandlerType getType() = 0; 58 enum EHandlerType { 59 EHT_Receive, 60 EHT_Transmit 61 }; 62 63 IsoHandler(int port); 64 65 IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq); 66 67 virtual ~IsoHandler(); 68 69 virtual bool init(); 70 71 int iterate() { if(m_handle) return raw1394_loop_iterate(m_handle); else return -1; }; 72 73 void setVerboseLevel(int l); 74 75 // no setter functions, because those would require a re-init 76 unsigned int getMaxPacketSize() { return m_max_packet_size;}; 77 unsigned int getBuffersize() { return m_buf_packets;}; 78 int getWakeupInterval() { return m_irq_interval;}; 79 80 int getPacketCount() {return m_packetcount;}; 81 void resetPacketCount() {m_packetcount=0;}; 82 83 int getDroppedCount() {return m_dropped;}; 84 void resetDroppedCount() {m_dropped=0;}; 85 86 virtual enum EHandlerType getType() = 0; 87 87 88 88 virtual bool start(int cycle) = 0; 89 89 virtual bool stop(); 90 90 91 92 93 94 95 96 97 98 99 100 101 102 91 int getFileDescriptor() { return raw1394_get_fd(m_handle);}; 92 93 void dumpInfo(); 94 95 bool inUse() {return (m_Client != 0) ;}; 96 virtual bool isStreamRegistered(IsoStream *s) {return (m_Client == s);}; 97 98 virtual bool registerStream(IsoStream *); 99 virtual bool unregisterStream(IsoStream *); 100 101 int getLocalNodeId() {return raw1394_get_local_id( m_handle );}; 102 int getPort() {return m_port;}; 103 103 104 104 virtual bool prepare() = 0; … … 117 117 bool setSyncMaster(FreebobUtil::TimeSource *t); 118 118 119 120 119 protected: 120 raw1394handle_t m_handle; 121 121 raw1394handle_t m_handle_util; 122 123 124 125 126 122 int m_port; 123 unsigned int m_buf_packets; 124 unsigned int m_max_packet_size; 125 int m_irq_interval; 126 127 127 unsigned int m_cyclecounter_ticks; 128 128 freebob_microsecs_t m_lastmeas_usecs; … … 130 130 float m_ticks_per_usec_dll_err2; 131 131 132 133 134 135 132 int m_packetcount; 133 int m_dropped; 134 135 IsoStream *m_Client; 136 136 137 137 FreebobUtil::TimeSource *m_TimeSource; 138 138 139 140 141 142 143 144 145 139 virtual int handleBusReset(unsigned int generation); 140 141 142 DECLARE_DEBUG_MODULE; 143 144 private: 145 static int busreset_handler(raw1394handle_t handle, unsigned int generation); 146 146 147 147 void initCycleCounter(); … … 165 165 { 166 166 167 168 169 170 171 172 173 174 167 public: 168 IsoRecvHandler(int port); 169 IsoRecvHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq); 170 virtual ~IsoRecvHandler(); 171 172 bool init(); 173 174 enum EHandlerType getType() { return EHT_Receive;}; 175 175 176 176 // int registerStream(IsoStream *); 177 177 // int unregisterStream(IsoStream *); 178 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 179 bool start(int cycle); 180 181 bool prepare(); 182 183 protected: 184 int handleBusReset(unsigned int generation); 185 186 private: 187 static enum raw1394_iso_disposition 188 iso_receive_handler(raw1394handle_t handle, unsigned char *data, 189 unsigned int length, unsigned char channel, 190 unsigned char tag, unsigned char sy, unsigned int cycle, 191 unsigned int dropped); 192 193 enum raw1394_iso_disposition 194 putPacket(unsigned char *data, unsigned int length, 195 unsigned char channel, unsigned char tag, unsigned char sy, 196 unsigned int cycle, unsigned int dropped); 197 197 198 198 }; … … 204 204 class IsoXmitHandler : public IsoHandler 205 205 { 206 207 208 209 210 211 212 213 214 215 216 217 206 public: 207 IsoXmitHandler(int port); 208 IsoXmitHandler(int port, unsigned int buf_packets, 209 unsigned int max_packet_size, int irq); 210 IsoXmitHandler(int port, unsigned int buf_packets, 211 unsigned int max_packet_size, int irq, 212 enum raw1394_iso_speed speed); 213 virtual ~IsoXmitHandler(); 214 215 bool init(); 216 217 enum EHandlerType getType() { return EHT_Transmit;}; 218 218 219 219 // int registerStream(IsoStream *); 220 220 // int unregisterStream(IsoStream *); 221 221 222 223 224 225 226 227 228 229 protected: 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 222 unsigned int getPreBuffers() {return m_prebuffers;}; 223 void setPreBuffers(unsigned int n) {m_prebuffers=n;}; 224 225 bool start(int cycle); 226 227 bool prepare(); 228 229 protected: 230 int handleBusReset(unsigned int generation); 231 232 private: 233 static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle, 234 unsigned char *data, unsigned int *length, 235 unsigned char *tag, unsigned char *sy, 236 int cycle, unsigned int dropped); 237 enum raw1394_iso_disposition 238 getPacket(unsigned char *data, unsigned int *length, 239 unsigned char *tag, unsigned char *sy, 240 int cycle, unsigned int dropped); 241 242 enum raw1394_iso_speed m_speed; 243 244 unsigned int m_prebuffers; 245 245 246 246 }; branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp
r360 r383 106 106 // updates the internal cycle counter caches of the handlers 107 107 void IsoHandlerManager::updateCycleCounters() { 108 109 108 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 109 110 110 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 111 111 it != m_IsoHandlers.end(); … … 140 140 bool IsoHandlerManager::registerHandler(IsoHandler *handler) 141 141 { 142 143 144 145 146 147 148 149 150 142 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 143 assert(handler); 144 145 m_IsoHandlers.push_back(handler); 146 147 handler->setVerboseLevel(getDebugLevel()); 148 149 // rebuild the fd map for poll()'ing. 150 return rebuildFdMap(); 151 151 152 152 } … … 206 206 void IsoHandlerManager::disablePolling(IsoStream *stream) { 207 207 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable polling on stream %p\n",stream); 208 209 210 211 212 213 214 215 208 int i=0; 209 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 210 it != m_IsoHandlers.end(); 211 ++it ) 212 { 213 if ((*it)->isStreamRegistered(stream)) { 214 m_poll_fds[i].events = 0; 215 m_poll_fds[i].revents = 0; 216 216 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling disabled\n"); 217 218 219 217 } 218 i++; 219 } 220 220 221 221 } … … 223 223 void IsoHandlerManager::enablePolling(IsoStream *stream) { 224 224 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable polling on stream %p\n",stream); 225 226 227 228 229 230 231 232 225 int i=0; 226 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 227 it != m_IsoHandlers.end(); 228 ++it ) 229 { 230 if ((*it)->isStreamRegistered(stream)) { 231 m_poll_fds[i].events = POLLIN; 232 m_poll_fds[i].revents = 0; 233 233 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling enabled\n"); 234 235 236 234 } 235 i++; 236 } 237 237 } 238 238 … … 444 444 445 445 void IsoHandlerManager::pruneHandlers() { 446 447 448 449 446 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 447 IsoHandlerVector toUnregister; 448 449 // find all handlers that are not in use 450 450 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 451 451 it != m_IsoHandlers.end(); 452 452 ++it ) 453 453 { 454 455 456 457 458 } 459 454 if(!((*it)->inUse())) { 455 debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it); 456 toUnregister.push_back(*it); 457 } 458 } 459 // delete them 460 460 for ( IsoHandlerVectorIterator it = toUnregister.begin(); 461 461 it != toUnregister.end(); 462 462 ++it ) 463 463 { 464 465 466 467 468 469 470 471 472 473 474 475 464 unregisterHandler(*it); 465 debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it); 466 467 // Now the handler's been unregistered it won't be reused 468 // again. Therefore it really needs to be formally deleted 469 // to free up the raw1394 handle. Otherwise things fall 470 // apart after several xrun recoveries as the system runs 471 // out of resources to support all the disused but still 472 // allocated raw1394 handles. At least this is the current 473 // theory as to why we end up with "memory allocation" 474 // failures after several Xrun recoveries. 475 delete *it; 476 476 } 477 477 … … 479 479 480 480 bool IsoHandlerManager::startHandlers() { 481 481 return startHandlers(-1); 482 482 } 483 483 484 484 bool IsoHandlerManager::startHandlers(int cycle) { 485 486 487 488 489 490 491 492 493 494 return false; 495 496 497 485 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 486 487 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 488 it != m_IsoHandlers.end(); 489 ++it ) 490 { 491 debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler (%p)\n",*it); 492 if(!(*it)->start(cycle)) { 493 debugOutput( DEBUG_LEVEL_VERBOSE, " could not start handler (%p)\n",*it); 494 return false; 495 } 496 } 497 498 498 return true; 499 499 } 500 500 501 501 bool IsoHandlerManager::stopHandlers() { 502 503 504 505 506 507 508 509 510 511 return false; 512 513 502 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 503 504 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 505 it != m_IsoHandlers.end(); 506 ++it ) 507 { 508 debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler (%p)\n",*it); 509 if(!(*it)->stop()){ 510 debugOutput( DEBUG_LEVEL_VERBOSE, " could not stop handler (%p)\n",*it); 511 return false; 512 } 513 } 514 514 return true; 515 515 } 516 516 517 517 void IsoHandlerManager::setVerboseLevel(int i) { 518 518 setDebugLevel(i); 519 519 520 520 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); … … 522 522 ++it ) 523 523 { 524 524 (*it)->setVerboseLevel(i); 525 525 } 526 526 } … … 528 528 void IsoHandlerManager::dumpInfo() { 529 529 debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n"); 530 531 530 int i=0; 531 532 532 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 533 533 it != m_IsoHandlers.end(); 534 534 ++it ) 535 535 { 536 537 538 536 debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it); 537 538 (*it)->dumpInfo(); 539 539 } 540 540 branches/streaming-rework/src/libstreaming/IsoHandlerManager.h
r360 r383 68 68 class IsoHandlerManager : public FreebobUtil::RunnableInterface 69 69 { 70 70 friend class StreamProcessorManager; 71 71 72 72 public: … … 75 75 virtual ~IsoHandlerManager(); 76 76 77 78 77 void setPollTimeout(int t) {m_poll_timeout=t;}; ///< set the timeout used for poll() 78 int getPollTimeout() {return m_poll_timeout;}; ///< get the timeout used for poll() 79 79 80 80 void setVerboseLevel(int l); ///< set the verbose level 81 81 82 82 void dumpInfo(); ///< print some information about the manager to stdout/stderr 83 83 84 85 84 bool registerStream(IsoStream *); ///< register an iso stream with the manager 85 bool unregisterStream(IsoStream *); ///< unregister an iso stream from the manager 86 86 87 88 89 87 bool startHandlers(); ///< start the managed ISO handlers 88 bool startHandlers(int cycle); ///< start the managed ISO handlers 89 bool stopHandlers(); ///< stop the managed ISO handlers 90 90 91 91 bool reset() {return true;}; ///< reset the ISO manager and all streams 92 92 93 94 95 96 93 bool prepare(); ///< prepare the ISO manager and all streams 94 95 void disablePolling(IsoStream *); ///< disables polling on a stream 96 void enablePolling(IsoStream *); ///< enables polling on a stream 97 97 98 98 public: 99 99 100 100 101 102 103 104 101 // RunnableInterface interface 102 bool Execute(); // note that this is called in we while(running) loop 103 bool Init(); 104 105 105 // iterate all handlers 106 106 bool iterate(); … … 109 109 void updateCycleCounters(); 110 110 111 112 113 111 // note: there is a disctinction between streams and handlers 112 // because one handler can serve multiple streams (in case of 113 // multichannel receive) 114 114 115 116 117 115 // only streams are allowed to be registered externally. 116 // we allocate a handler if we need one, otherwise the stream 117 // is assigned to another handler 118 118 119 120 119 // the collection of handlers 120 IsoHandlerVector m_IsoHandlers; 121 121 122 123 124 122 bool registerHandler(IsoHandler *); 123 bool unregisterHandler(IsoHandler *); 124 void pruneHandlers(); 125 125 126 127 126 // the collection of streams 127 IsoStreamVector m_IsoStreams; 128 128 129 130 131 132 129 // poll stuff 130 int m_poll_timeout; 131 struct pollfd *m_poll_fds; 132 int m_poll_nfds; 133 133 134 134 bool rebuildFdMap(); 135 135 136 136 137 137 DECLARE_DEBUG_MODULE; 138 138 139 139 }; branches/streaming-rework/src/libstreaming/IsoStream.cpp
r244 r383 39 39 enum raw1394_iso_disposition 40 40 IsoStream::putPacket(unsigned char *data, unsigned int length, 41 42 41 unsigned char channel, unsigned char tag, unsigned char sy, 42 unsigned int cycle, unsigned int dropped) { 43 43 44 45 46 44 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, 45 "received packet: length=%d, channel=%d, cycle=%d\n", 46 length, channel, cycle ); 47 47 48 48 return RAW1394_ISO_OK; 49 49 } 50 50 51 51 enum raw1394_iso_disposition 52 52 IsoStream::getPacket(unsigned char *data, unsigned int *length, 53 54 55 56 57 53 unsigned char *tag, unsigned char *sy, 54 int cycle, unsigned int dropped, unsigned int max_length) { 55 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, 56 "sending packet: length=%d, cycle=%d\n", 57 *length, cycle ); 58 58 59 60 61 62 59 memcpy(data,&cycle,sizeof(cycle)); 60 *length=sizeof(cycle); 61 *tag = 1; 62 *sy = 0; 63 63 64 64 65 65 return RAW1394_ISO_OK; 66 66 } 67 67 68 68 int IsoStream::getNodeId() { 69 70 71 72 69 if (m_handler) { 70 return m_handler->getLocalNodeId(); 71 } 72 return -1; 73 73 } 74 74 … … 77 77 { 78 78 79 80 81 82 83 79 debugOutputShort( DEBUG_LEVEL_NORMAL, " Address : %p\n",this); 80 debugOutputShort( DEBUG_LEVEL_NORMAL, " Stream type : %s\n", 81 (this->getType()==EST_Receive ? "Receive" : "Transmit")); 82 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : %d, %d\n", 83 m_port, m_channel); 84 84 85 85 }; 86 86 87 87 bool IsoStream::setChannel(int c) { 88 88 debugOutput( DEBUG_LEVEL_VERBOSE, "setting channel to %d\n",c); 89 89 90 91 90 m_channel=c; 91 return true; 92 92 } 93 93 94 94 95 95 bool IsoStream::reset() { 96 97 96 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 97 return true; 98 98 } 99 99 100 100 bool IsoStream::prepare() { 101 102 101 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 102 return true; 103 103 } 104 104 105 105 bool IsoStream::init() { 106 107 106 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 107 return true; 108 108 109 109 } 110 110 111 111 void IsoStream::setHandler(IsoHandler *h) { 112 113 112 debugOutput( DEBUG_LEVEL_VERBOSE, "setting handler of isostream %p to %p\n", this,h); 113 m_handler=h; 114 114 } 115 115 116 116 void IsoStream::clearHandler() { 117 117 debugOutput( DEBUG_LEVEL_VERBOSE, "clearing handler of isostream %p\n", this); 118 118 119 119 m_handler=0; branches/streaming-rework/src/libstreaming/IsoStream.h
r244 r383 44 44 class IsoStream 45 45 { 46 47 48 46 friend class IsoHandler; 47 friend class IsoRecvHandler; 48 friend class IsoXmitHandler; 49 49 50 50 public: 51 51 52 53 54 55 52 enum EStreamType { 53 EST_Receive, 54 EST_Transmit 55 }; 56 56 57 57 IsoStream(enum EStreamType type) 58 58 : m_type(type), m_channel(-1), m_port(0), m_handler(0) 59 59 {}; 60 60 IsoStream(enum EStreamType type, int port) 61 61 : m_type(type), m_channel(-1), m_port(port), m_handler(0) 62 62 {}; 63 63 virtual ~IsoStream() 64 64 {}; 65 66 virtual void setVerboseLevel(int l) { setDebugLevel( l ); }; 65 67 66 virtual void setVerboseLevel(int l) { setDebugLevel( l ); }; 68 int getChannel() {return m_channel;}; 69 bool setChannel(int c); 67 70 68 int getChannel() {return m_channel;}; 69 bool setChannel(int c); 71 int getPort() {return m_port;}; 70 72 71 int getPort() {return m_port;};73 enum EStreamType getType() { return m_type;}; 72 74 73 enum EStreamType getType() { return m_type;}; 75 virtual unsigned int getPacketsPerPeriod() {return 1;}; 76 virtual unsigned int getMaxPacketSize() {return 1024;}; //FIXME: arbitrary 77 78 virtual bool init(); 74 79 75 virtual unsigned int getPacketsPerPeriod() {return 1;}; 76 virtual unsigned int getMaxPacketSize() {return 1024;}; //FIXME: arbitrary 77 78 virtual bool init(); 80 virtual enum raw1394_iso_disposition 81 putPacket(unsigned char *data, unsigned int length, 82 unsigned char channel, unsigned char tag, unsigned char sy, 83 unsigned int cycle, unsigned int dropped); 84 virtual enum raw1394_iso_disposition 85 getPacket(unsigned char *data, unsigned int *length, 86 unsigned char *tag, unsigned char *sy, 87 int cycle, unsigned int dropped, unsigned int max_length); 79 88 80 virtual enum raw1394_iso_disposition 81 putPacket(unsigned char *data, unsigned int length, 82 unsigned char channel, unsigned char tag, unsigned char sy, 83 unsigned int cycle, unsigned int dropped); 84 virtual enum raw1394_iso_disposition 85 getPacket(unsigned char *data, unsigned int *length, 86 unsigned char *tag, unsigned char *sy, 87 int cycle, unsigned int dropped, unsigned int max_length); 89 void dumpInfo(); 88 90 89 void dumpInfo(); 91 int getNodeId(); 92 93 virtual bool reset(); 94 virtual bool prepare(); 95 96 protected: 90 97 91 int getNodeId(); 92 93 virtual bool reset(); 94 virtual bool prepare(); 95 96 protected: 98 void setHandler( IsoHandler * h) ; 99 void clearHandler(); 97 100 98 void setHandler( IsoHandler * h) ; 99 void clearHandler(); 101 enum EStreamType m_type; 102 int m_channel; 103 int m_port; 100 104 101 enum EStreamType m_type; 102 int m_channel; 103 int m_port; 105 IsoHandler *m_handler; 104 106 105 IsoHandler *m_handler; 106 107 DECLARE_DEBUG_MODULE; 107 DECLARE_DEBUG_MODULE; 108 108 109 109 }; branches/streaming-rework/src/libstreaming/MotuStreamProcessor.cpp
r333 r383 27 27 * 28 28 */ 29 29 30 30 31 31 #include "MotuStreamProcessor.h" branches/streaming-rework/src/libstreaming/StreamProcessor.cpp
r265 r383 60 60 { 61 61 62 63 64 65 66 67 68 69 70 62 debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor information\n"); 63 debugOutputShort( DEBUG_LEVEL_NORMAL, " Iso stream info:\n"); 64 65 IsoStream::dumpInfo(); 66 debugOutputShort( DEBUG_LEVEL_NORMAL, " Frame counter : %d\n", m_framecounter); 67 debugOutputShort( DEBUG_LEVEL_NORMAL, " Xruns : %d\n", m_xruns); 68 debugOutputShort( DEBUG_LEVEL_NORMAL, " Running : %d\n", m_running); 69 debugOutputShort( DEBUG_LEVEL_NORMAL, " Enabled : %d\n", !m_disabled); 70 71 71 m_PeriodStat.dumpInfo(); 72 72 m_PacketStat.dumpInfo(); … … 78 78 bool StreamProcessor::init() 79 79 { 80 81 82 80 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 81 82 return IsoStream::init(); 83 83 } 84 84 … … 89 89 bool StreamProcessor::reset() { 90 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 91 debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n"); 92 93 resetFrameCounter(); 94 95 resetXrunCounter(); 96 97 // loop over the ports to reset them 98 if (!PortManager::resetPorts()) { 99 debugFatal("Could not reset ports\n"); 100 return false; 101 } 102 103 // reset the iso stream 104 if (!IsoStream::reset()) { 105 debugFatal("Could not reset isostream\n"); 106 return false; 107 } 108 return true; 109 109 110 110 } branches/streaming-rework/src/libstreaming/StreamProcessor.h
r312 r383 50 50 public PortManager { 51 51 52 52 friend class StreamProcessorManager; 53 53 54 54 public: 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 55 enum EProcessorType { 56 E_Receive, 57 E_Transmit 58 }; 59 60 StreamProcessor(enum IsoStream::EStreamType type, int port, int framerate); 61 virtual ~StreamProcessor(); 62 63 virtual enum raw1394_iso_disposition 64 putPacket(unsigned char *data, unsigned int length, 65 unsigned char channel, unsigned char tag, unsigned char sy, 66 unsigned int cycle, unsigned int dropped) = 0; 67 virtual enum raw1394_iso_disposition 68 getPacket(unsigned char *data, unsigned int *length, 69 unsigned char *tag, unsigned char *sy, 70 int cycle, unsigned int dropped, unsigned int max_length) = 0; 71 72 virtual enum EProcessorType getType() =0; 73 74 bool xrunOccurred() { return (m_xruns>0);}; 75 75 76 76 /** … … 84 84 * @return 85 85 */ 86 87 88 86 virtual bool isOnePeriodReady()=0; 87 88 unsigned int getNbPeriodsReady() { if(m_period) return m_framecounter/m_period; else return 0;}; 89 89 virtual void decrementFrameCounter(); 90 90 virtual void incrementFrameCounter(int nbframes); 91 92 91 92 // move to private? 93 93 void resetFrameCounter(); 94 94 void resetXrunCounter(); 95 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 96 bool isRunning(); ///< returns true if there is some stream data processed 97 void enable(); ///< enable the stream processing 98 void disable() {m_disabled=true;}; ///< disable the stream processing 99 bool isEnabled() {return !m_disabled;}; 100 101 virtual bool transfer(); ///< transfer the buffer contents from/to client 102 103 virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun) 104 105 virtual bool prepare(); ///< prepare the streams & buffers (e.g. prefill) 106 107 virtual void dumpInfo(); 108 109 virtual bool init(); 110 111 virtual void setVerboseLevel(int l); 112 113 virtual bool preparedForStop() {return true;}; 114 virtual bool preparedForStart() {return true;}; 115 115 116 116 protected: 117 117 118 118 119 120 121 122 123 124 125 119 void setManager(StreamProcessorManager *manager) {m_manager=manager;}; 120 void clearManager() {m_manager=0;}; 121 122 unsigned int m_nb_buffers; ///< cached from manager->getNbBuffers(), the number of periods to buffer 123 unsigned int m_period; ///< cached from manager->getPeriod(), the period size 124 125 unsigned int m_xruns; 126 126 signed int m_framecounter; 127 127 128 129 130 131 132 133 128 unsigned int m_framerate; 129 130 StreamProcessorManager *m_manager; 131 132 bool m_running; 133 bool m_disabled; 134 134 135 135 StreamStatistics m_PacketStat; … … 140 140 141 141 DECLARE_DEBUG_MODULE; 142 142 143 143 144 144 }; branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp
r360 r383 195 195 bool StreamProcessorManager::Init() 196 196 { 197 198 199 200 201 202 197 debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing runner...\n"); 198 199 // no xrun has occurred (yet) 200 m_xrun_happened=false; 201 202 if(sem_init(&m_period_semaphore, 0, 0)) { 203 203 debugFatal( "Cannot init packet transfer semaphore\n"); 204 205 204 debugFatal( " Error: %s\n",strerror(errno)); 205 return false; 206 206 } 207 208 207 208 return true; 209 209 } 210 210 … … 249 249 250 250 bool period_ready=true; 251 bool xrun_has_occured=false;251 bool xrun_has_occured=false; 252 252 bool this_period_ready; 253 253 … … 258 258 return false; 259 259 } 260 260 261 261 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " RCV PROC: "); 262 262 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); … … 381 381 // start the runner thread 382 382 m_isoManagerThread->Start(); 383 383 384 384 debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to start running...\n"); 385 385 // we have to wait until all streamprocessors indicate that they are running … … 592 592 if(!stop()) { 593 593 debugFatal("Could not stop.\n"); 594 594 return false; 595 595 } 596 596 … … 633 633 if(!start()) { 634 634 debugFatal("Could not start.\n"); 635 635 return false; 636 636 } 637 637 branches/streaming-rework/src/libstreaming/StreamProcessorManager.h
r341 r383 58 58 public: 59 59 60 61 60 StreamProcessorManager(unsigned int period, unsigned int nb_buffers); 61 virtual ~StreamProcessorManager(); 62 62 63 64 63 bool init(); ///< to be called immediately after the construction 64 bool prepare(); ///< to be called after the processors are registered 65 65 66 67 66 virtual void setVerboseLevel(int l); 67 void dumpInfo(); 68 68 69 70 71 69 // this is the setup API 70 bool registerProcessor(StreamProcessor *processor); ///< start managing a streamprocessor 71 bool unregisterProcessor(StreamProcessor *processor); ///< stop managing a streamprocessor 72 72 73 74 75 73 void setPeriodSize(unsigned int period); 74 void setPeriodSize(unsigned int period, unsigned int nb_buffers); 75 int getPeriodSize() {return m_period;}; 76 76 77 78 77 void setNbBuffers(unsigned int nb_buffers); 78 int getNbBuffers() {return m_nb_buffers;}; 79 79 80 81 82 80 int getPortCount(enum Port::E_PortType, enum Port::E_Direction); 81 int getPortCount(enum Port::E_Direction); 82 Port* getPortByIndex(int idx, enum Port::E_Direction); 83 83 84 85 86 84 // the client-side functions 85 bool xrunOccurred(); 86 int getXrunCount() {return m_xruns;}; 87 87 88 88 bool waitForPeriod(); ///< wait for the next period 89 89 90 91 90 bool transfer(); ///< transfer the buffer contents from/to client 91 bool transfer(enum StreamProcessor::EProcessorType); ///< transfer the buffer contents from/to client (single processor type) 92 92 93 93 bool handleXrun(); ///< reset the streams & buffers after xrun 94 94 95 96 95 bool start(); 96 bool stop(); 97 97 98 98 bool setThreadParameters(bool rt, int priority); … … 100 100 // the ISO-side functions 101 101 protected: 102 103 104 105 102 int signalWaiters(); // call this to signal a period boundary 103 // RunnableInterface interface 104 bool Execute(); // note that this is called in we while(running) loop 105 bool Init(); 106 106 107 108 107 // thread sync primitives 108 sem_t m_period_semaphore; 109 109 110 110 bool m_xrun_happened; 111 111 112 112 bool m_thread_realtime; 113 113 int m_thread_priority; 114 114 115 116 117 115 // processor list 116 StreamProcessorVector m_ReceiveProcessors; 117 StreamProcessorVector m_TransmitProcessors; 118 118 119 120 121 122 123 119 unsigned int m_nb_buffers; 120 unsigned int m_period; 121 unsigned int m_xruns; 122 123 IsoHandlerManager *m_isoManager; 124 124 125 126 125 FreebobUtil::PosixThread *m_streamingThread; 126 FreebobUtil::PosixThread *m_isoManagerThread; 127 127 128 128 unsigned int m_nbperiods; branches/streaming-rework/src/libutil/TimeSource.h
r360 r383 39 39 public: 40 40 41 42 41 TimeSource(); 42 virtual ~TimeSource(); 43 43 44 44 virtual freebob_microsecs_t getCurrentTime()=0; 45 45 virtual freebob_microsecs_t getCurrentTimeAsUsecs()=0; 46 46 47 47 protected: 48 48 branches/streaming-rework/src/Makefile.am
r365 r383 36 36 rme/rme_avdevice.h 37 37 38 libfreebob_la_SOURCES = 38 libfreebob_la_SOURCES = \ 39 39 iavdevice.h \ 40 configrom.cpp\41 csr1212.c\42 devicemanager.cpp\43 freebob.cpp\44 xmlparser.c\40 configrom.cpp \ 41 csr1212.c \ 42 devicemanager.cpp \ 43 freebob.cpp \ 44 xmlparser.c \ 45 45 threads.h \ 46 46 bebob/bebob_avdevice.h \ 47 bebob/bebob_avdevice.cpp\47 bebob/bebob_avdevice.cpp \ 48 48 bebob/bebob_avdevice_xml.cpp \ 49 49 bebob/bebob_avdevice_subunit.h \ 50 bebob/bebob_avdevice_subunit.cpp\50 bebob/bebob_avdevice_subunit.cpp \ 51 51 bebob/bebob_avplug.h \ 52 bebob/bebob_avplug.cpp\53 bebob/bebob_avplug_xml.cpp\52 bebob/bebob_avplug.cpp \ 53 bebob/bebob_avplug_xml.cpp \ 54 54 bebob/bebob_functionblock.h \ 55 55 bebob/bebob_functionblock.cpp \ … … 59 59 bebob/bebob_dl_codes.cpp \ 60 60 bebob/bebob_dl_bcd.h \ 61 bebob/bebob_dl_bcd.cpp\61 bebob/bebob_dl_bcd.cpp \ 62 62 motu/motu_avdevice.cpp \ 63 63 motu/motu_avdevice.h \ … … 65 65 rme/rme_avdevice.h \ 66 66 bounce/bounce_avdevice.h \ 67 bounce/bounce_avdevice.cpp\67 bounce/bounce_avdevice.cpp \ 68 68 maudio/maudio_avdevice.h \ 69 maudio/maudio_avdevice.cpp\70 libfreebobavc/avc_connect.cpp\71 libfreebobavc/avc_definitions.cpp\72 libfreebobavc/avc_extended_cmd_generic.cpp\73 libfreebobavc/avc_extended_plug_info.cpp\74 libfreebobavc/avc_extended_stream_format.cpp\75 libfreebobavc/avc_extended_subunit_info.cpp\76 libfreebobavc/avc_function_block.cpp\69 maudio/maudio_avdevice.cpp \ 70 libfreebobavc/avc_connect.cpp \ 71 libfreebobavc/avc_definitions.cpp \ 72 libfreebobavc/avc_extended_cmd_generic.cpp \ 73 libfreebobavc/avc_extended_plug_info.cpp \ 74 libfreebobavc/avc_extended_stream_format.cpp \ 75 libfreebobavc/avc_extended_subunit_info.cpp \ 76 libfreebobavc/avc_function_block.cpp \ 77 77 libfreebobavc/avc_function_block.h \ 78 libfreebobavc/avc_generic.cpp\79 libfreebobavc/avc_plug_info.cpp\80 libfreebobavc/avc_signal_source.cpp\81 libfreebobavc/avc_subunit_info.cpp\82 libfreebobavc/avc_unit_info.cpp\83 libfreebobavc/ieee1394service.cpp\78 libfreebobavc/avc_generic.cpp \ 79 libfreebobavc/avc_plug_info.cpp \ 80 libfreebobavc/avc_signal_source.cpp \ 81 libfreebobavc/avc_subunit_info.cpp \ 82 libfreebobavc/avc_unit_info.cpp \ 83 libfreebobavc/ieee1394service.cpp \ 84 84 libfreebobavc/avc_serialize.cpp \ 85 85 libfreebobavc/avc_connect.h \ … … 98 98 debugmodule/debugmodule.h \ 99 99 debugmodule/debugmodule.cpp \ 100 libstreaming/cip.c\100 libstreaming/cip.c \ 101 101 libstreaming/cyclecounter.h \ 102 libstreaming/freebob_streaming.cpp\103 libstreaming/IsoHandler.cpp\104 libstreaming/IsoHandlerManager.cpp\105 libstreaming/IsoStream.cpp\106 libstreaming/PacketBuffer.cpp\102 libstreaming/freebob_streaming.cpp \ 103 libstreaming/IsoHandler.cpp \ 104 libstreaming/IsoHandlerManager.cpp \ 105 libstreaming/IsoStream.cpp \ 106 libstreaming/PacketBuffer.cpp \ 107 107 libstreaming/PortManager.cpp \ 108 libstreaming/Port.cpp\109 libstreaming/StreamProcessor.cpp\110 libstreaming/StreamProcessorManager.cpp\108 libstreaming/Port.cpp \ 109 libstreaming/StreamProcessor.cpp \ 110 libstreaming/StreamProcessorManager.cpp \ 111 111 libstreaming/AmdtpPortInfo.cpp \ 112 112 libstreaming/AmdtpPort.cpp \ 113 113 libstreaming/AmdtpStreamProcessor.cpp \ 114 114 libstreaming/ringbuffer.c \ 115 libstreaming/streamstatistics.cpp\115 libstreaming/streamstatistics.cpp \ 116 116 libstreaming/MotuStreamProcessor.cpp \ 117 117 libstreaming/MotuPort.cpp \ … … 121 121 libutil/PosixThread.h \ 122 122 libutil/Thread.h \ 123 libutil/DelayLockedLoop.cpp\124 libutil/PosixThread.cpp\123 libutil/DelayLockedLoop.cpp \ 124 libutil/PosixThread.cpp \ 125 125 libutil/Time.c \ 126 126 libutil/Time.h \ 127 127 libutil/TimeSource.cpp \ 128 128 libutil/TimeSource.h \ 129 libutil/SystemTimeSource.cpp\129 libutil/SystemTimeSource.cpp \ 130 130 libutil/SystemTimeSource.h \ 131 131 libutil/cycles.h \ branches/streaming-rework/tests/test-sytmonitor.cpp
r360 r383 1 1 /*************************************************************************** 2 2 Copyright (C) 2005 by Pieter Palmers * 3 3 * 4 5 6 7 4 This program is free software; you can redistribute it and/or modify * 5 it under the terms of the GNU General Public License as published by * 6 the Free Software Foundation; either version 2 of the License, or * 7 (at your option) any later version. * 8 8 * 9 10 11 12 9 This program is distributed in the hope that it will be useful, * 10 but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 GNU General Public License for more details. * 13 13 * 14 15 16 17 18 14 You should have received a copy of the GNU General Public License * 15 along with this program; if not, write to the * 16 Free Software Foundation, Inc., * 17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 ***************************************************************************/ 19 19 20 20 #ifdef HAVE_CONFIG_H … … 92 92 93 93 switch (key) { 94 95 94 case 'p': 95 if (arg) { 96 96 arguments->port = strtol( arg, &tail, 0 ); 97 97 if ( errno ) { … … 99 99 return ARGP_ERR_UNKNOWN; 100 100 } 101 101 } else { 102 102 if ( errno ) { 103 103 fprintf( stderr, "Could not parse 'port' argumen\n" ); 104 104 return ARGP_ERR_UNKNOWN; 105 105 } 106 107 108 106 } 107 break; 108 case 'R': 109 109 arguments->realtime = true; 110 111 112 110 break; 111 case 'r': 112 if (arg) { 113 113 arguments->rtprio = strtol( arg, &tail, 0 ); 114 114 if ( errno ) { … … 116 116 return ARGP_ERR_UNKNOWN; 117 117 } 118 119 120 121 118 } 119 break; 120 case ARGP_KEY_ARG: 121 if (state->arg_num >= 128) { 122 122 // Too many arguments. 123 123 argp_usage( state ); 124 125 126 127 128 129 130 131 124 } 125 126 if(sscanf( arg, "%d,%d", 127 &arguments->args[state->arg_num].port, 128 &arguments->args[state->arg_num].channel) != 2) { 129 fprintf( stderr, "Could not parse port-channel specification ('%s')\n", arg); 130 131 } else { 132 132 printf("Adding Port %d, Channel %d to list...\n", 133 134 135 136 137 138 139 133 arguments->args[state->arg_num].port, 134 arguments->args[state->arg_num].channel); 135 arguments->nb_combos++; 136 } 137 break; 138 case ARGP_KEY_END: 139 if (state->arg_num < 1) { 140 140 // Not enough arguments. 141 141 argp_usage( state ); 142 143 144 145 142 } 143 break; 144 default: 145 return ARGP_ERR_UNKNOWN; 146 146 } 147 147 return 0; … … 154 154 static void sighandler (int sig) 155 155 { 156 156 run = 0; 157 157 } 158 158 … … 162 162 int target_channel_1=0; 163 163 int target_channel_2=0; 164 165 166 167 168 169 170 164 bool run_realtime=false; 165 int realtime_prio=20; 166 int nb_iter; 167 int i; 168 struct sched_param params; 169 170 IsoHandlerManager *m_isoManager=NULL; 171 171 PosixThread * m_isoManagerThread=NULL; 172 172 173 173 SytMonitor *monitors[128]; 174 174 int stream_offset_ticks[128]; 175 175 176 176 struct arguments arguments; 177 177 … … 193 193 194 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 195 run=1; 196 197 run_realtime=arguments.realtime; 198 realtime_prio=arguments.rtprio; 199 200 signal (SIGINT, sighandler); 201 signal (SIGPIPE, sighandler); 202 203 debugOutput(DEBUG_LEVEL_NORMAL, "Freebob SYT monitor\n"); 204 205 m_isoManager=new IsoHandlerManager(); 206 207 if(!m_isoManager) { 208 debugOutput(DEBUG_LEVEL_NORMAL, "Could not create IsoHandlerManager\n"); 209 goto finish; 210 } 211 212 m_isoManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 213 214 214 // the thread to execute the manager 215 216 217 218 219 220 221 222 223 224 225 226 227 debugOutput(DEBUG_LEVEL_NORMAL, "Registering SytMonitor %d\n",i);228 229 // add a stream to the manager so that it has something to do230 monitors[i]=new SytMonitor(arguments.args[i].port);231 232 if (!monitors[i]) {233 debugOutput(DEBUG_LEVEL_NORMAL, "Could not create SytMonitor %d\n", i);234 goto finish;235 }236 237 monitors[i]->setVerboseLevel(DEBUG_LEVEL_VERBOSE);238 239 if (!monitors[i]->init()) {240 debugOutput(DEBUG_LEVEL_NORMAL, "Could not init SytMonitor %d\n", i);241 goto finish;242 }243 244 monitors[i]->setChannel(arguments.args[i].channel);245 246 if(!m_isoManager->registerStream(monitors[i])) {215 m_isoManagerThread=new PosixThread( 216 m_isoManager, 217 run_realtime, realtime_prio, 218 PTHREAD_CANCEL_DEFERRED); 219 220 if(!m_isoManagerThread) { 221 debugOutput(DEBUG_LEVEL_NORMAL, "Could not create iso manager thread\n"); 222 goto finish; 223 } 224 225 // register monitors 226 for (i=0;i<arguments.nb_combos;i++) { 227 debugOutput(DEBUG_LEVEL_NORMAL, "Registering SytMonitor %d\n",i); 228 229 // add a stream to the manager so that it has something to do 230 monitors[i]=new SytMonitor(arguments.args[i].port); 231 232 if (!monitors[i]) { 233 debugOutput(DEBUG_LEVEL_NORMAL, "Could not create SytMonitor %d\n", i); 234 goto finish; 235 } 236 237 monitors[i]->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 238 239 if (!monitors[i]->init()) { 240 debugOutput(DEBUG_LEVEL_NORMAL, "Could not init SytMonitor %d\n", i); 241 goto finish; 242 } 243 244 monitors[i]->setChannel(arguments.args[i].channel); 245 246 if(!m_isoManager->registerStream(monitors[i])) { 247 247 debugOutput(DEBUG_LEVEL_NORMAL, "Could not register SytMonitor %d\n", i); 248 goto finish;249 }248 goto finish; 249 } 250 250 } 251 252 253 254 255 256 257 258 259 251 252 253 debugOutput(DEBUG_LEVEL_NORMAL, "Preparing IsoHandlerManager...\n"); 254 if (!m_isoManager->prepare()) { 255 debugOutput(DEBUG_LEVEL_NORMAL, "Could not prepare isoManager\n"); 256 goto finish; 257 } 258 259 debugOutput(DEBUG_LEVEL_NORMAL, "Starting ISO manager sync update thread...\n"); 260 260 261 261 // start the runner thread 262 262 m_isoManagerThread->Start(); 263 263 264 265 266 267 268 269 270 if (arguments.realtime) {271 // get rt priority for this thread too.272 params.sched_priority = arguments.rtprio + 1;273 if (pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶ms)) {274 debugWarning("Couldn't set realtime prio for main thread...");275 }276 }277 278 // do the actual work279 nb_iter=0;280 264 debugOutput(DEBUG_LEVEL_NORMAL, "Starting IsoHandlers...\n"); 265 if (!m_isoManager->startHandlers(0)) { 266 debugOutput(DEBUG_LEVEL_NORMAL, "Could not start handlers...\n"); 267 goto finish; 268 } 269 270 if (arguments.realtime) { 271 // get rt priority for this thread too. 272 params.sched_priority = arguments.rtprio + 1; 273 if (pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶ms)) { 274 debugWarning("Couldn't set realtime prio for main thread..."); 275 } 276 } 277 278 // do the actual work 279 nb_iter=0; 280 while(run) { 281 281 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"--- Iterate ---\n"); 282 282 … … 325 325 326 326 if(cif.cycle==master_cif.cycle 327 327 && cif.seconds==master_cif.seconds) { // this is the one 328 328 debugOutput(DEBUG_LEVEL_VERY_VERBOSE," GOOD : [%2d: %04us %04uc, %04X]\n", 329 329 i,cif.seconds, cif.cycle,cif.syt); … … 339 339 cif.pres_ticks += TICKS_PER_SECOND*128; 340 340 } 341 341 // average out the offset 342 342 int err=(((long)master_cif.pres_ticks) - ((long)cif.pres_ticks)); 343 343 … … 383 383 if ((cif.seconds < master_cif.seconds) || 384 384 ((cif.seconds == master_cif.seconds) 385 385 && (cif.cycle < master_cif.cycle))) { 386 386 387 387 debugOutput(DEBUG_LEVEL_VERY_VERBOSE," LAGS : [%2d: %04us %04uc, %04X]\n", … … 419 419 } 420 420 421 // show info every x iterations421 // show info every x iterations 422 422 if ((nb_iter++ % 4000)==0) { 423 m_isoManager->dumpInfo();424 for (i=0;i<arguments.nb_combos;i++) {425 monitors[i]->dumpInfo();423 m_isoManager->dumpInfo(); 424 for (i=0;i<arguments.nb_combos;i++) { 425 monitors[i]->dumpInfo(); 426 426 debugOutput(DEBUG_LEVEL_NORMAL," ==> Stream offset: %10d ticks\n",stream_offset_ticks[i]); 427 }428 }429 430 431 432 433 434 435 436 437 438 439 440 441 442 427 } 428 } 429 } 430 431 debugOutput(DEBUG_LEVEL_NORMAL, "Stopping handlers...\n"); 432 if(!m_isoManager->stopHandlers()) { 433 debugOutput(DEBUG_LEVEL_NORMAL, "Could not stop ISO handlers\n"); 434 goto finish; 435 } 436 437 // stop the sync thread 438 debugOutput(DEBUG_LEVEL_NORMAL, "Stopping ISO manager sync update thread...\n"); 439 m_isoManagerThread->Stop(); 440 441 // unregister monitors 442 for (i=0;i<arguments.nb_combos;i++) { 443 443 debugOutput(DEBUG_LEVEL_NORMAL, "Unregistering SytMonitor %d\n",i); 444 444 445 445 if(!m_isoManager->unregisterStream(monitors[i])) { 446 446 debugOutput(DEBUG_LEVEL_NORMAL, "Could not unregister SytMonitor %d\n",i); 447 447 goto finish; 448 449 448 } 449 delete monitors[i]; 450 450 } 451 452 451 452 delete m_isoManagerThread; 453 453 delete m_isoManager; 454 454 455 455 finish: 456 debugOutput(DEBUG_LEVEL_NORMAL, "Bye...\n"); 457 458 delete DebugModuleManager::instance(); 459 460 return EXIT_SUCCESS; 456 debugOutput(DEBUG_LEVEL_NORMAL, "Bye...\n"); 457 delete DebugModuleManager::instance(); 458 459 return EXIT_SUCCESS; 461 460 }