Various enhancements and fixes:
- fixed handling of Max samples per packet Source parameter in the WebUI and ad> - fixed max number of channels in the Sink configuration of the WebUI - fixed tic_frame_size_at_1fs daemon parameter documentation - changed daemon default frame size to 48000Hz
This commit is contained in:
		
							parent
							
								
									9c4913f7e4
								
							
						
					
					
						commit
						f8d37dda74
					
				| @ -221,8 +221,7 @@ where: | ||||
| 
 | ||||
| > **tic\_frame\_size\_at\_1fs** | ||||
| > JSON number specifying the TIC frame size at 1FS in samples, valid range is from 6 to 192 samples. | ||||
| > This global setting is used to determine the driver base timer period. For example with a value of 192 samples this period is set to 4ms and the outgoing RTP packets are scheduled for being sent every 4ms causing an average latency greater than 4ms.      | ||||
| > A user is able to configure Sources whose max number of samples range from 125μs (6 samples) to the value of this parameter. For example with a value of 48 samples a user is able to configure Sources with a max number of samples ranging from 125μs (6 samples) to 1ms (48 samples) and packets will be affected by a 1ms latency. | ||||
| > This global setting is used to determine the driver base timer period. For example with a value of 192 samples this period is set to 4ms and the outgoing RTP packets are scheduled for being sent every 4ms resulting on an average latency greater than 4ms. | ||||
| 
 | ||||
| > **max\_tic\_frame\_size** | ||||
| > JSON number specifying the max tick frame size. This is currently set to 1024. | ||||
|  | ||||
| @ -65,7 +65,7 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) { | ||||
|       config.max_tic_frame_size_ > 1024) | ||||
|     config.max_tic_frame_size_ = 1024; | ||||
|   if (config.sample_rate_ == 0) | ||||
|     config.sample_rate_ = 44100; | ||||
|     config.sample_rate_ = 48000; | ||||
|   boost::system::error_code ec; | ||||
|   ip::address_v4::from_string(config.rtp_mcast_base_.c_str(), ec); | ||||
|   if (ec) { | ||||
|  | ||||
| @ -119,7 +119,7 @@ class Config { | ||||
|   uint32_t playout_delay_{0}; | ||||
|   uint32_t tic_frame_size_at_1fs_{48}; | ||||
|   uint32_t max_tic_frame_size_{1024}; | ||||
|   uint32_t sample_rate_{44100}; | ||||
|   uint32_t sample_rate_{48000}; | ||||
|   std::string rtp_mcast_base_{"239.1.0.1"}; | ||||
|   std::string sap_mcast_addr_{"224.2.127.254"}; | ||||
|   uint16_t rtp_port_{5004}; | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
|   "playout_delay": 0, | ||||
|   "tic_frame_size_at_1fs": 48, | ||||
|   "max_tic_frame_size": 1024, | ||||
|   "sample_rate": 44100, | ||||
|   "sample_rate": 48000, | ||||
|   "rtp_mcast_base": "239.1.0.1", | ||||
|   "rtp_port": 5004, | ||||
|   "ptp_domain": 0, | ||||
|  | ||||
| @ -455,9 +455,7 @@ std::error_code SessionManager::add_source(const StreamSource& source) { | ||||
|   info.stream.m_byNbOfChannels = source.map.size(); | ||||
|   strncpy(info.stream.m_cCodec, source.codec.c_str(), | ||||
|           sizeof(info.stream.m_cCodec) - 1); | ||||
|   info.stream.m_ui32MaxSamplesPerPacket =  | ||||
|     source.max_samples_per_packet > config_->get_tic_frame_size_at_1fs() ? | ||||
|       config_->get_tic_frame_size_at_1fs() : source.max_samples_per_packet; | ||||
|   info.stream.m_ui32MaxSamplesPerPacket = source.max_samples_per_packet; | ||||
|   info.stream.m_ui32SamplingRate = driver_->get_current_sample_rate(); // last set from driver or config
 | ||||
|   info.stream.m_uiId = source.id; | ||||
|   info.stream.m_ui32RTCPSrcIP = config_->get_ip_addr(); | ||||
|  | ||||
| @ -140,12 +140,13 @@ class Config extends Component { | ||||
|             <th align="left"> <label>TIC frame size @1FS (samples) </label> </th> | ||||
|             <th align="left"> | ||||
|               <select value={this.state.ticFrameSizeAt1fs} onChange={e => this.setState({ticFrameSizeAt1fs: e.target.value})}> | ||||
|                 <option value="6">6 - 125μs@48Khz</option> | ||||
|                 <option value="12">12 - 250μs@48Khz</option> | ||||
|                 <option value="16">16 - 333μs@48Khz</option> | ||||
|                 <option value="48">48 - 1ms@48Khz</option> | ||||
|                 <option value="96">96 - 2ms@48Khz</option> | ||||
|                 <option value="192">192 - 4ms@48Khz</option> | ||||
|                 <option value="6">6 - 125μs</option> | ||||
|                 <option value="12">12 - 250μs</option> | ||||
|                 <option value="16">16 - 333μs</option> | ||||
|                 <option value="24">24 - 500μs</option> | ||||
|                 <option value="48">48 - 1ms</option> | ||||
|                 <option value="96">96 - 2ms</option> | ||||
|                 <option value="192">192 - 4ms</option> | ||||
|               </select> | ||||
|             </th> | ||||
|           </tr> | ||||
|  | ||||
| @ -117,7 +117,7 @@ class SinkEdit extends Component { | ||||
|   onCancel() { | ||||
|     this.props.closeEdit(); | ||||
|   } | ||||
|   | ||||
| 
 | ||||
|   onChangeChannels(e) { | ||||
|     if (e.currentTarget.checkValidity()) { | ||||
|       let channels = parseInt(e.target.value, 10); | ||||
| @ -213,7 +213,7 @@ class SinkEdit extends Component { | ||||
|             </tr> | ||||
|             <tr> | ||||
|               <th align="left"> <label>Channels</label> </th> | ||||
|               <th align="left"> <input type='number' min='1' max='8' className='input-number' value={this.state.channels} onChange={this.onChangeChannels} required/> </th> | ||||
|               <th align="left"> <input type='number' min='1' max='64' className='input-number' value={this.state.channels} onChange={this.onChangeChannels} required/> </th> | ||||
|             </tr> | ||||
|             <tr> | ||||
|               <th align="left">Audio Channels map</th> | ||||
|  | ||||
| @ -44,6 +44,7 @@ class SourceEdit extends Component { | ||||
|   static propTypes = { | ||||
|     source: PropTypes.object.isRequired, | ||||
|     ticFrameSizeAt1fs: PropTypes.number.isRequired, | ||||
|     sampleRate: PropTypes.number.isRequired, | ||||
|     applyEdit: PropTypes.func.isRequired, | ||||
|     closeEdit: PropTypes.func.isRequired, | ||||
|     editIsOpen: PropTypes.bool.isRequired, | ||||
| @ -59,8 +60,6 @@ class SourceEdit extends Component { | ||||
|       name: this.props.source.name, | ||||
|       nameErr: false, | ||||
|       io: this.props.source.io, | ||||
|       maxSamplesPerPacket: (this.props.source.max_samples_per_packet > this.props.ticFrameSizeAt1fs) ?  | ||||
|                               this.props.ticFrameSizeAt1fs : this.props.source.max_samples_per_packet, | ||||
|       codec: this.props.source.codec, | ||||
|       ttl: this.props.source.ttl, | ||||
|       ttlErr: false, | ||||
| @ -70,8 +69,9 @@ class SourceEdit extends Component { | ||||
|       refclkPtpTraceable: this.props.source.refclk_ptp_traceable, | ||||
|       channels: this.props.source.map.length, | ||||
|       channelsErr: false, | ||||
|       maxChannels: Math.floor(max_packet_size / (this.props.source.max_samples_per_packet * (this.props.source.codec === 'L16' ? 2 : 3))), | ||||
|       map: this.props.source.map, | ||||
|       maxSamplesPerPacket: this.getMaxSamplesPerPacket(), | ||||
|       maxChannels: this.getMaxChannels(this.props.source.codec, this.getMaxSamplesPerPacket()), | ||||
|       audioMap: [] | ||||
|     } | ||||
|     let v; | ||||
| @ -87,6 +87,10 @@ class SourceEdit extends Component { | ||||
|     this.onChangeCodec = this.onChangeCodec.bind(this); | ||||
|     this.inputIsValid = this.inputIsValid.bind(this); | ||||
|     this.checkMaxSamplesPerPacket = this.checkMaxSamplesPerPacket.bind(this); | ||||
|     this.getMaxSamplesPerPacket = this.getMaxSamplesPerPacket.bind(this); | ||||
|     this.getnFS = this.getnFS.bind(this); | ||||
|     this.getPacketDuration = this.getPacketDuration.bind(this); | ||||
|     this.getMaxChannels = this.getMaxChannels.bind(this); | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
| @ -120,16 +124,21 @@ class SourceEdit extends Component { | ||||
|   onCancel() { | ||||
|     this.props.closeEdit(); | ||||
|   } | ||||
|    | ||||
|   getMaxChannels(codec, samples) { | ||||
|     let maxChannels = Math.floor(max_packet_size / (samples * (codec === 'L16' ? 2 : 3))); | ||||
|     return maxChannels > 64 ? 64 : maxChannels; | ||||
|   } | ||||
| 
 | ||||
|   onChangeMaxSamplesPerPacket(e) { | ||||
|     let samples = parseInt(e.target.value, 10); | ||||
|     let maxChannels = Math.floor(max_packet_size / (samples * (this.state.codec === 'L16' ? 2 : 3))); | ||||
|     let maxChannels = this.getMaxChannels(this.state.codec, samples); | ||||
|     this.setState({ maxSamplesPerPacket: samples, maxChannels: maxChannels, channelsErr: this.state.channels > maxChannels }); | ||||
|   } | ||||
| 
 | ||||
|   onChangeCodec(e) { | ||||
|     let codec = e.target.value; | ||||
|     let maxChannels = Math.floor(max_packet_size / (this.state.maxSamplesPerPacket * (codec === 'L16' ? 2 : 3))); | ||||
|     let maxChannels = this.getMaxChannels(this.state.codec, this.state.maxSamplesPerPacket); | ||||
|     this.setState({ codec: codec, maxChannels: maxChannels, channelsErr: this.state.channels > maxChannels }); | ||||
|   } | ||||
|   | ||||
| @ -156,8 +165,47 @@ class SourceEdit extends Component { | ||||
|     this.setState({ map: map }); | ||||
|   } | ||||
| 
 | ||||
|   checkMaxSamplesPerPacket(value) { | ||||
|     return this.props.ticFrameSizeAt1fs >= value; | ||||
|   getnFS() { | ||||
|     switch(this.props.sampleRate) { | ||||
|       case 384000: | ||||
|       case 352800: | ||||
|         return 8; | ||||
|         break; | ||||
|       case 192000: | ||||
|       case 176400: | ||||
|         return 4; | ||||
|         break; | ||||
|       case 96000: | ||||
|       case 88200: | ||||
|         return 2; | ||||
|         break; | ||||
|       case 48000: | ||||
|       case 44100: | ||||
|       default: | ||||
|         return 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   checkMaxSamplesPerPacket(samples) { | ||||
|     return (samples <= (this.props.ticFrameSizeAt1fs * this.getnFS())); | ||||
|   } | ||||
| 
 | ||||
|   getMaxSamplesPerPacket() { | ||||
|     return (this.props.source.max_samples_per_packet > (this.props.ticFrameSizeAt1fs * this.getnFS())) ?  | ||||
|             (this.props.ticFrameSizeAt1fs * this.getnFS()) : this.props.source.max_samples_per_packet; | ||||
|   } | ||||
| 
 | ||||
|   getPacketDuration(samples) { | ||||
|     let duration = (samples * 1000000) / this.props.sampleRate; | ||||
|     if (duration >= 1000) { | ||||
|       duration /= 1000; | ||||
|       if (duration == Math.round(duration))  | ||||
|         return Math.round(duration).toString() + 'ms'; | ||||
|       else | ||||
|         return (Math.round(duration * 1000) / 1000).toString() + 'ms'; | ||||
|     } | ||||
|     else | ||||
|       return Math.round(duration).toString() + 'μs'; | ||||
|   } | ||||
| 
 | ||||
|   inputIsValid() { | ||||
| @ -193,12 +241,12 @@ class SourceEdit extends Component { | ||||
|               <th align="left"> <label>Max samples per packet </label> </th> | ||||
|               <th align="left">  | ||||
| 	        <select value={this.state.maxSamplesPerPacket} onChange={this.onChangeMaxSamplesPerPacket}> | ||||
|                   <option value="6" disabled={this.checkMaxSamplesPerPacket(6) ? undefined : true}>6 - 125μs@48Khz</option> | ||||
|                   <option value="12" disabled={this.checkMaxSamplesPerPacket(12) ? undefined : true}>12 - 250μs@48Khz</option> | ||||
|                   <option value="16" disabled={this.checkMaxSamplesPerPacket(16) ? undefined : true}>16 - 333μs@48Khz</option> | ||||
|                   <option value="48" disabled={this.checkMaxSamplesPerPacket(48) ? undefined : true}>48 - 1ms@48Khz</option> | ||||
|                   <option value="96" disabled={this.checkMaxSamplesPerPacket(96) ? undefined : true}>96 - 2ms@48Khz</option> | ||||
|                   <option value="192" disabled={this.checkMaxSamplesPerPacket(192) ? undefined : true}>192 - 4ms@48Khz</option> | ||||
|                   <option value="6" disabled={this.checkMaxSamplesPerPacket(6) ? undefined : true}>6 - {this.getPacketDuration(6)}</option> | ||||
|                   <option value="12" disabled={this.checkMaxSamplesPerPacket(12) ? undefined : true}>12 - {this.getPacketDuration(12)}</option> | ||||
|                   <option value="16" disabled={this.checkMaxSamplesPerPacket(16) ? undefined : true}>16 - {this.getPacketDuration(16)}</option> | ||||
|                   <option value="48" disabled={this.checkMaxSamplesPerPacket(48) ? undefined : true}>48 - {this.getPacketDuration(48)}</option> | ||||
|                   <option value="96" disabled={this.checkMaxSamplesPerPacket(96) ? undefined : true}>96 - {this.getPacketDuration(96)}</option> | ||||
|                   <option value="192" disabled={this.checkMaxSamplesPerPacket(192) ? undefined : true}>192 - {this.getPacketDuration(192)}</option> | ||||
|                 </select> | ||||
|               </th> | ||||
|             </tr> | ||||
|  | ||||
| @ -146,6 +146,7 @@ class Sources extends Component { | ||||
|       infoIsOpen: false,  | ||||
|       removeIsOpen: false, | ||||
|       ticFrameSizeAt1fs: '', | ||||
|       sampleRate: '', | ||||
|       editTitle: ''  | ||||
|     }; | ||||
|     this.onInfoClick = this.onInfoClick.bind(this); | ||||
| @ -171,7 +172,7 @@ class Sources extends Component { | ||||
|     RestAPI.getConfig() | ||||
|       .then(response => response.json()) | ||||
|       .then( | ||||
|         data => this.setState( { isConfigLoading: false, ticFrameSizeAt1fs: data.tic_frame_size_at_1fs })) | ||||
|         data => this.setState( { isConfigLoading: false, ticFrameSizeAt1fs: data.tic_frame_size_at_1fs, sampleRate: data.sample_rate })) | ||||
|       .catch(err => this.setState({ isConfigLoading: false })); | ||||
|   } | ||||
| 
 | ||||
| @ -281,6 +282,7 @@ class Sources extends Component { | ||||
|           editTitle={this.state.editTitle}  | ||||
| 	  isEdit={this.state.isEdit} | ||||
|           ticFrameSizeAt1fs={this.state.ticFrameSizeAt1fs} | ||||
|           sampleRate={this.state.sampleRate} | ||||
| 	  source={this.state.source} /> | ||||
|            : undefined } | ||||
|        { this.state.removeIsOpen ? | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user