Various enhancements and fixes:
- fixed handling of Max samples per packet Source parameter in the WebUI and added computation of the real frame duration - fixed max number of channels configurable for a Sink in the WebUI - fixed tic_frame_size_at_1fs daemon parameter documentation - changed daemon default sample_rate parameter to 48000 Hz
This commit is contained in:
parent
9c4913f7e4
commit
07c2b35777
@ -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