Changeset 2078
- Timestamp:
- 03/10/12 06:03:53 (12 years ago)
- Files:
-
- trunk/libffado/libffado/ffado.h (modified) (1 diff)
- trunk/libffado/src/devicemanager.cpp (modified) (1 diff)
- trunk/libffado/src/devicemanager.h (modified) (1 diff)
- trunk/libffado/src/ffado.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/generic/Port.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp (modified) (5 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.h (modified) (2 diffs)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/StreamProcessorManager.h (modified) (1 diff)
- trunk/libffado/src/libutil/TimestampedBuffer.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/libffado/ffado.h
r1928 r2078 258 258 259 259 /** 260 * This permits the setting of the period size at some time after 261 * initialisation. The primary use of this function is to support the 262 * setbufsize functionality of JACK. 263 * 264 * @param dev the ffado device 265 * @param period the new period size 266 * @return 0 on success, non-zero if an error occurred 267 */ 268 int ffado_streaming_set_period_size(ffado_device_t *dev, unsigned int period); 269 270 /** 260 271 * preparation should be done after setting all per-stream parameters 261 272 * the way you want them. being buffer data type etc... trunk/libffado/src/devicemanager.cpp
r2074 r2078 1009 1009 1010 1010 bool 1011 DeviceManager::setPeriodSize(unsigned int period) { 1012 // Useful for cases where only the period size needs adjusting 1013 m_processorManager->setPeriodSize(period); 1014 return true; 1015 } 1016 1017 bool 1011 1018 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) { 1012 1019 m_processorManager->setPeriodSize(period); trunk/libffado/src/devicemanager.h
r1763 r2078 96 96 bool resetStreaming(); 97 97 enum eWaitResult waitForPeriod(); 98 bool setPeriodSize(unsigned int period); 98 99 bool setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers); 99 100 trunk/libffado/src/ffado.cpp
r1498 r2078 184 184 // we are ready! 185 185 return dev; 186 } 187 188 int ffado_streaming_set_period_size(ffado_device_t *dev, unsigned int period) { 189 if (!dev->m_deviceManager->setPeriodSize(period)) 190 { 191 debugFatal( "Could not set period size of device manager\n" ); 192 return -1; 193 } 194 return 0; 186 195 } 187 196 trunk/libffado/src/libstreaming/generic/Port.cpp
r1498 r2078 91 91 bool Port::setBufferSize(unsigned int newsize) { 92 92 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffersize to %d for port %s\n",newsize,m_Name.c_str()); 93 if (m_State != E_Created ) {94 debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State);93 if (m_State != E_Created && m_disabled == false) { 94 debugFatal("Port (%s) not in E_Created/disabled state: %d\n",m_Name.c_str(),m_State); 95 95 return false; 96 96 } trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp
r1972 r2078 95 95 96 96 bool 97 StreamProcessor::periodSizeChanged(unsigned int new_periodsize) { 98 // This is called by the StreamProcessorManager whenever the period size 99 // is changed via setPeriodSize(). If the stream processor needs to do 100 // anything in response it can be done in this method. Buffer size 101 // changes should only ever be made when streaming is not active. 102 // 103 // Return false if there was a problem dealing with the resize. 104 if (m_state!=ePS_Stopped && m_state!=ePS_Created) { 105 debugOutput(DEBUG_LEVEL_WARNING, "(%p) period change should only be done with streaming stopped\n", this); 106 return false; 107 } 108 109 // make the scratch buffer one period of frames long 110 m_scratch_buffer_size_bytes = new_periodsize * getEventsPerFrame() * getEventSize(); 111 debugOutput( DEBUG_LEVEL_VERBOSE, " Allocate scratch buffer of %zd quadlets\n", m_scratch_buffer_size_bytes); 112 if(m_scratch_buffer) delete[] m_scratch_buffer; 113 m_scratch_buffer = new byte_t[m_scratch_buffer_size_bytes]; 114 if(m_scratch_buffer == NULL) { 115 debugFatal("Could not allocate scratch buffer\n"); 116 return false; 117 } 118 119 // set the parameters of ports we can: 120 // we want the audio ports to be period buffered, 121 // and the midi ports to be packet buffered 122 for ( PortVectorIterator it = m_Ports.begin(); 123 it != m_Ports.end(); 124 ++it ) 125 { 126 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 127 if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) { 128 debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize()); 129 return false; 130 } 131 } 132 133 if (!setupDataBuffer()) { 134 debugFatal("Could not setup data buffer\n"); 135 return false; 136 } 137 138 return updateState(); 139 } 140 141 bool 97 142 StreamProcessor::handleBusResetDo() 98 143 { … … 168 213 * Buffer management and manipulation * 169 214 ***********************************************/ 215 bool 216 StreamProcessor::setupDataBuffer() { 217 assert(m_data_buffer); 218 219 unsigned int ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize(); 220 ringbuffer_size_frames += m_extra_buffer_frames; 221 ringbuffer_size_frames += 1; // to ensure that we can fit it all in there 222 223 bool result = true; 224 225 m_correct_last_timestamp = false; 226 227 // initialize internal buffer 228 result &= m_data_buffer->setBufferSize(ringbuffer_size_frames); 229 230 result &= m_data_buffer->setEventSize( getEventSize() ); 231 result &= m_data_buffer->setEventsPerFrame( getEventsPerFrame() ); 232 if(getType() == ePT_Receive) { 233 result &= m_data_buffer->setUpdatePeriod( getNominalFramesPerPacket() ); 234 } else { 235 result &= m_data_buffer->setUpdatePeriod( m_StreamProcessorManager.getPeriodSize() ); 236 } 237 // Completing the buffer's setup and calling the prepare() method is not 238 // applicable unless the nominal rate (m_ticks_per_frame) has been 239 // configured. This may not be the case when setupDataBuffer() is 240 // called from prepare() via periodSizeChanged(), but will be when called 241 // from doStop() and from periodSizeChanged() via the stream processor's 242 // setPeriodSize() method. 243 if (m_ticks_per_frame > 0) { 244 result &= m_data_buffer->setNominalRate(m_ticks_per_frame); 245 result &= m_data_buffer->setWrapValue(128L * TICKS_PER_SECOND); 246 result &= m_data_buffer->setBandwidth(STREAMPROCESSOR_DLL_FAST_BW_HZ / (double)TICKS_PER_SECOND); 247 248 result &= m_data_buffer->prepare(); // FIXME: the name 249 250 debugOutput(DEBUG_LEVEL_VERBOSE, "DLL info: nominal tpf: %f, update period: %d, bandwidth: %e 1/ticks (%e Hz)\n", 251 m_data_buffer->getNominalRate(), m_data_buffer->getUpdatePeriod(), m_data_buffer->getBandwidth(), m_data_buffer->getBandwidth() * TICKS_PER_SECOND); 252 } 253 254 return result; 255 } 256 170 257 void 171 258 StreamProcessor::getBufferHeadTimestamp(ffado_timestamp_t *ts, signed int *fc) … … 1070 1157 debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare SP (%p)...\n", this); 1071 1158 1072 // make the scratch buffer one period of frames long 1073 m_scratch_buffer_size_bytes = m_StreamProcessorManager.getPeriodSize() * getEventsPerFrame() * getEventSize(); 1074 debugOutput( DEBUG_LEVEL_VERBOSE, " Allocate scratch buffer of %zd quadlets\n", m_scratch_buffer_size_bytes); 1075 if(m_scratch_buffer) delete[] m_scratch_buffer; 1076 m_scratch_buffer = new byte_t[m_scratch_buffer_size_bytes]; 1077 if(m_scratch_buffer == NULL) { 1078 debugFatal("Could not allocate scratch buffer\n"); 1159 if (periodSizeChanged(m_StreamProcessorManager.getPeriodSize()) == false) 1079 1160 return false; 1080 } 1081 1082 // set the parameters of ports we can: 1083 // we want the audio ports to be period buffered, 1084 // and the midi ports to be packet buffered 1085 for ( PortVectorIterator it = m_Ports.begin(); 1086 it != m_Ports.end(); 1087 ++it ) 1088 { 1089 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 1090 if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) { 1091 debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize()); 1092 return false; 1093 } 1094 } 1161 1095 1162 // the API specific settings of the ports should already be set, 1096 1163 // as this is called from the processorManager->prepare() … … 1355 1422 1356 1423 float ticks_per_frame; 1357 unsigned int ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize();1358 ringbuffer_size_frames += m_extra_buffer_frames;1359 ringbuffer_size_frames += 1; // to ensure that we can fit it all in there1360 1424 1361 1425 debugOutput(DEBUG_LEVEL_VERBOSE, "Enter from state: %s\n", ePSToString(m_state)); … … 1372 1436 debugOutput(DEBUG_LEVEL_VERBOSE, "Initializing remote ticks/frame to %f\n", ticks_per_frame); 1373 1437 1374 // initialize internal buffer 1375 result &= m_data_buffer->setBufferSize(ringbuffer_size_frames); 1376 1377 result &= m_data_buffer->setEventSize( getEventSize() ); 1378 result &= m_data_buffer->setEventsPerFrame( getEventsPerFrame() ); 1379 if(getType() == ePT_Receive) { 1380 result &= m_data_buffer->setUpdatePeriod( getNominalFramesPerPacket() ); 1381 } else { 1382 result &= m_data_buffer->setUpdatePeriod( m_StreamProcessorManager.getPeriodSize() ); 1383 } 1384 result &= m_data_buffer->setNominalRate(ticks_per_frame); 1385 result &= m_data_buffer->setWrapValue(128L * TICKS_PER_SECOND); 1386 result &= m_data_buffer->setBandwidth(STREAMPROCESSOR_DLL_FAST_BW_HZ / (double)TICKS_PER_SECOND); 1387 result &= m_data_buffer->prepare(); // FIXME: the name 1388 1389 debugOutput(DEBUG_LEVEL_VERBOSE, "DLL info: nominal tpf: %f, update period: %d, bandwidth: %e 1/ticks (%e Hz)\n", 1390 m_data_buffer->getNominalRate(), m_data_buffer->getUpdatePeriod(), m_data_buffer->getBandwidth(), m_data_buffer->getBandwidth() * TICKS_PER_SECOND); 1438 result &= setupDataBuffer(); 1391 1439 break; 1392 1440 case ePS_DryRunning: trunk/libffado/src/libstreaming/generic/StreamProcessor.h
r1972 r2078 63 63 ///> returns the type of the streamprocessor 64 64 virtual enum eProcessorType getType() { return m_processor_type; }; 65 66 ///> notification of a buffer size change 67 virtual bool periodSizeChanged(unsigned int new_periodsize); 65 68 private: 66 69 // this can only be set by the constructor … … 299 302 //--- data buffering and accounting 300 303 public: 304 bool setupDataBuffer(); 301 305 void getBufferHeadTimestamp ( ffado_timestamp_t *ts, signed int *fc ); 302 306 void getBufferTailTimestamp ( ffado_timestamp_t *ts, signed int *fc ); trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r1998 r2078 307 307 } 308 308 309 void StreamProcessorManager::setPeriodSize(unsigned int period) { 310 // This method is called early in the initialisation sequence to set the 311 // initial period size. However, at that point in time the stream 312 // processors haven't been registered so they won't have their buffers 313 // configured from here. The initial allocation of the stream processor 314 // (SP) buffers happens from within the SP prepare() method. 315 // 316 // SP period size changes will normally only be acted on from here 317 // if the change comes about due to a runtime change in the buffer size, 318 // as happens via jack's setbufsize facility for example. 319 320 if (period == m_period) 321 return; 322 323 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting period size to %d (was %d)\n", period, m_period); 324 m_period = period; 325 326 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 327 it != m_ReceiveProcessors.end(); 328 ++it ) 329 { 330 if ((*it)->periodSizeChanged(period) == false) 331 debugWarning("receive stream processor %p couldn't set period size\n", *it); 332 } 333 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 334 it != m_TransmitProcessors.end(); 335 ++it ) 336 { 337 if ((*it)->periodSizeChanged(period) == false) 338 debugWarning("transmit stream processor %p couldn't set period size\n", *it); 339 } 340 341 // Keep the activity timeout in sync with the new period size. See 342 // also comments about this in prepare(). 343 if (m_nominal_framerate > 0) { 344 int timeout_usec = 2*1000LL * 1000LL * m_period / m_nominal_framerate; 345 debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec); 346 setActivityWaitTimeoutUsec(timeout_usec); 347 } 348 } 349 309 350 bool StreamProcessorManager::setSyncSource(StreamProcessor *s) { 310 351 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting sync source to (%p)\n", s); trunk/libffado/src/libstreaming/StreamProcessorManager.h
r1972 r2078 85 85 bool unregisterProcessor(StreamProcessor *processor); ///< stop managing a streamprocessor 86 86 87 void setPeriodSize(unsigned int period) 88 {m_period = period;}; 87 void setPeriodSize(unsigned int period); 89 88 unsigned int getPeriodSize() 90 89 {return m_period;}; trunk/libffado/src/libutil/TimestampedBuffer.cpp
r1981 r2078 396 396 m_cluster_size = m_events_per_frame * m_event_size; 397 397 m_process_block_size = m_cluster_size * FRAMES_PER_PROCESS_BLOCK; 398 if (m_process_buffer != NULL) 399 free(m_process_buffer); 398 400 if( !(m_process_buffer=(char *)calloc(m_process_block_size, 1))) { 399 401 debugFatal("Could not allocate temporary cluster buffer\n");