OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 last_rec_callbacks_(0), | 52 last_rec_callbacks_(0), |
53 play_callbacks_(0), | 53 play_callbacks_(0), |
54 last_play_callbacks_(0), | 54 last_play_callbacks_(0), |
55 rec_samples_(0), | 55 rec_samples_(0), |
56 last_rec_samples_(0), | 56 last_rec_samples_(0), |
57 play_samples_(0), | 57 play_samples_(0), |
58 last_play_samples_(0), | 58 last_play_samples_(0), |
59 last_log_stat_time_(0), | 59 last_log_stat_time_(0), |
60 max_rec_level_(0), | 60 max_rec_level_(0), |
61 max_play_level_(0), | 61 max_play_level_(0), |
62 num_rec_level_is_zero_(0) { | 62 num_rec_level_is_zero_(0), |
63 rec_stat_count_(0), | |
64 play_stat_count_(0) { | |
63 LOG(INFO) << "AudioDeviceBuffer::ctor"; | 65 LOG(INFO) << "AudioDeviceBuffer::ctor"; |
64 } | 66 } |
65 | 67 |
66 AudioDeviceBuffer::~AudioDeviceBuffer() { | 68 AudioDeviceBuffer::~AudioDeviceBuffer() { |
67 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 69 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
68 LOG(INFO) << "AudioDeviceBuffer::~dtor"; | 70 LOG(INFO) << "AudioDeviceBuffer::~dtor"; |
69 | 71 |
70 size_t total_diff_time = 0; | 72 size_t total_diff_time = 0; |
71 int num_measurements = 0; | 73 int num_measurements = 0; |
72 LOG(INFO) << "[playout diff time => #measurements]"; | 74 LOG(INFO) << "[playout diff time => #measurements]"; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 return 0; | 229 return 0; |
228 } | 230 } |
229 | 231 |
230 int32_t AudioDeviceBuffer::StopOutputFileRecording() { | 232 int32_t AudioDeviceBuffer::StopOutputFileRecording() { |
231 LOG(LS_WARNING) << "Not implemented"; | 233 LOG(LS_WARNING) << "Not implemented"; |
232 return 0; | 234 return 0; |
233 } | 235 } |
234 | 236 |
235 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, | 237 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, |
236 size_t num_samples) { | 238 size_t num_samples) { |
237 const size_t rec_bytes_per_sample = [&] { | 239 const size_t rec_channels = [&] { |
238 rtc::CritScope lock(&lock_); | 240 rtc::CritScope lock(&lock_); |
239 return rec_bytes_per_sample_; | 241 return rec_channels_; |
240 }(); | 242 }(); |
241 // Copy the complete input buffer to the local buffer. | 243 // Copy the complete input buffer to the local buffer. |
242 const size_t size_in_bytes = num_samples * rec_bytes_per_sample; | 244 const size_t size_in_bytes = num_samples * rec_channels * sizeof(int16_t); |
243 const size_t old_size = rec_buffer_.size(); | 245 const size_t old_size = rec_buffer_.size(); |
244 rec_buffer_.SetData(static_cast<const uint8_t*>(audio_buffer), size_in_bytes); | 246 rec_buffer_.SetData(static_cast<const uint8_t*>(audio_buffer), size_in_bytes); |
245 // Keep track of the size of the recording buffer. Only updated when the | 247 // Keep track of the size of the recording buffer. Only updated when the |
246 // size changes, which is a rare event. | 248 // size changes, which is a rare event. |
247 if (old_size != rec_buffer_.size()) { | 249 if (old_size != rec_buffer_.size()) { |
248 LOG(LS_INFO) << "Size of recording buffer: " << rec_buffer_.size(); | 250 LOG(LS_INFO) << "Size of recording buffer: " << rec_buffer_.size(); |
249 } | 251 } |
252 // Derive a new level value twice per second. | |
253 int16_t max_abs = 0; | |
254 if (++rec_stat_count_ >= 50) { | |
255 RTC_DCHECK_LE(rec_stat_count_, 50); | |
kwiberg-webrtc
2016/10/21 09:04:43
It doesn't make a lot of difference, but you could
henrika (OOO until Aug 14)
2016/10/21 09:12:18
Done.
| |
256 const size_t size = num_samples * rec_channels; | |
257 // Returns the largest absolute value in a signed 16-bit vector. | |
258 max_abs = WebRtcSpl_MaxAbsValueW16( | |
259 reinterpret_cast<const int16_t*>(rec_buffer_.data()), size); | |
260 rec_stat_count_ = 0; | |
261 } | |
250 // Update some stats but do it on the task queue to ensure that the members | 262 // Update some stats but do it on the task queue to ensure that the members |
251 // are modified and read on the same thread. | 263 // are modified and read on the same thread. Note that |max_abs| will be |
264 // zero in most calls and then have no effect of the stats. It is only updated | |
265 // approximately two times per second and can then change the stats. | |
kwiberg-webrtc
2016/10/21 09:04:43
Ah, OK, I see now. Thanks.
henrika (OOO until Aug 14)
2016/10/21 09:12:18
Acknowledged.
| |
252 task_queue_.PostTask(rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, | 266 task_queue_.PostTask(rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, |
253 audio_buffer, num_samples)); | 267 max_abs, num_samples)); |
254 return 0; | 268 return 0; |
255 } | 269 } |
256 | 270 |
257 int32_t AudioDeviceBuffer::DeliverRecordedData() { | 271 int32_t AudioDeviceBuffer::DeliverRecordedData() { |
258 rtc::CritScope lock(&lock_cb_); | 272 rtc::CritScope lock(&lock_cb_); |
259 if (!audio_transport_cb_) { | 273 if (!audio_transport_cb_) { |
260 LOG(LS_WARNING) << "Invalid audio transport"; | 274 LOG(LS_WARNING) << "Invalid audio transport"; |
261 return 0; | 275 return 0; |
262 } | 276 } |
263 const size_t rec_bytes_per_sample = [&] { | 277 const size_t rec_bytes_per_sample = [&] { |
(...skipping 20 matching lines...) Expand all Loading... | |
284 // position/index corresponds to time differences (in milliseconds) between | 298 // position/index corresponds to time differences (in milliseconds) between |
285 // two successive playout callbacks, and the stored value is the number of | 299 // two successive playout callbacks, and the stored value is the number of |
286 // times a given time difference was found. | 300 // times a given time difference was found. |
287 int64_t now_time = rtc::TimeMillis(); | 301 int64_t now_time = rtc::TimeMillis(); |
288 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_); | 302 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_); |
289 // Truncate at 500ms to limit the size of the array. | 303 // Truncate at 500ms to limit the size of the array. |
290 diff_time = std::min(kMaxDeltaTimeInMs, diff_time); | 304 diff_time = std::min(kMaxDeltaTimeInMs, diff_time); |
291 last_playout_time_ = now_time; | 305 last_playout_time_ = now_time; |
292 playout_diff_times_[diff_time]++; | 306 playout_diff_times_[diff_time]++; |
293 | 307 |
294 const size_t play_bytes_per_sample = [&] { | 308 const size_t play_channels = [&] { |
295 rtc::CritScope lock(&lock_); | 309 rtc::CritScope lock(&lock_); |
296 return play_bytes_per_sample_; | 310 return play_channels_; |
297 }(); | 311 }(); |
298 | 312 |
299 // The consumer can change the request size on the fly and we therefore | 313 // The consumer can change the request size on the fly and we therefore |
300 // resize the buffer accordingly. Also takes place at the first call to this | 314 // resize the buffer accordingly. Also takes place at the first call to this |
301 // method. | 315 // method. |
316 const size_t play_bytes_per_sample = play_channels * sizeof(int16_t); | |
302 const size_t size_in_bytes = num_samples * play_bytes_per_sample; | 317 const size_t size_in_bytes = num_samples * play_bytes_per_sample; |
303 if (play_buffer_.size() != size_in_bytes) { | 318 if (play_buffer_.size() != size_in_bytes) { |
304 play_buffer_.SetSize(size_in_bytes); | 319 play_buffer_.SetSize(size_in_bytes); |
305 LOG(LS_INFO) << "Size of playout buffer: " << play_buffer_.size(); | 320 LOG(LS_INFO) << "Size of playout buffer: " << play_buffer_.size(); |
306 } | 321 } |
307 | 322 |
308 rtc::CritScope lock(&lock_cb_); | 323 rtc::CritScope lock(&lock_cb_); |
309 | 324 |
310 // It is currently supported to start playout without a valid audio | 325 // It is currently supported to start playout without a valid audio |
311 // transport object. Leads to warning and silence. | 326 // transport object. Leads to warning and silence. |
312 if (!audio_transport_cb_) { | 327 if (!audio_transport_cb_) { |
313 LOG(LS_WARNING) << "Invalid audio transport"; | 328 LOG(LS_WARNING) << "Invalid audio transport"; |
314 return 0; | 329 return 0; |
315 } | 330 } |
316 | 331 |
332 // Retrieve new 16-bit PCM audio data using the audio transport instance. | |
317 int64_t elapsed_time_ms = -1; | 333 int64_t elapsed_time_ms = -1; |
318 int64_t ntp_time_ms = -1; | 334 int64_t ntp_time_ms = -1; |
319 size_t num_samples_out(0); | 335 size_t num_samples_out(0); |
320 uint32_t res = audio_transport_cb_->NeedMorePlayData( | 336 uint32_t res = audio_transport_cb_->NeedMorePlayData( |
321 num_samples, play_bytes_per_sample_, play_channels_, play_sample_rate_, | 337 num_samples, play_bytes_per_sample_, play_channels, play_sample_rate_, |
322 play_buffer_.data(), num_samples_out, &elapsed_time_ms, &ntp_time_ms); | 338 play_buffer_.data(), num_samples_out, &elapsed_time_ms, &ntp_time_ms); |
323 if (res != 0) { | 339 if (res != 0) { |
324 LOG(LS_ERROR) << "NeedMorePlayData() failed"; | 340 LOG(LS_ERROR) << "NeedMorePlayData() failed"; |
325 } | 341 } |
326 | 342 |
327 // Update some stats but do it on the task queue to ensure that access of | 343 // Derive a new level value twice per second. |
328 // members is serialized hence avoiding usage of locks. | 344 int16_t max_abs = 0; |
345 if (++play_stat_count_ >= 50) { | |
346 RTC_DCHECK_LE(play_stat_count_, 50); | |
347 const size_t size = num_samples * play_channels; | |
348 // Returns the largest absolute value in a signed 16-bit vector. | |
349 max_abs = WebRtcSpl_MaxAbsValueW16( | |
350 reinterpret_cast<const int16_t*>(play_buffer_.data()), size); | |
351 play_stat_count_ = 0; | |
352 } | |
353 // Update some stats but do it on the task queue to ensure that the members | |
354 // are modified and read on the same thread. Note that |max_abs| will be | |
355 // zero in most calls and then have no effect of the stats. It is only updated | |
356 // approximately two times per second and can then change the stats. | |
329 task_queue_.PostTask(rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, | 357 task_queue_.PostTask(rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, |
330 play_buffer_.data(), num_samples_out)); | 358 max_abs, num_samples_out)); |
331 return static_cast<int32_t>(num_samples_out); | 359 return static_cast<int32_t>(num_samples_out); |
332 } | 360 } |
333 | 361 |
334 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { | 362 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { |
335 RTC_DCHECK_GT(play_buffer_.size(), 0u); | 363 RTC_DCHECK_GT(play_buffer_.size(), 0u); |
336 const size_t play_bytes_per_sample = [&] { | 364 const size_t play_bytes_per_sample = [&] { |
337 rtc::CritScope lock(&lock_); | 365 rtc::CritScope lock(&lock_); |
338 return play_bytes_per_sample_; | 366 return play_bytes_per_sample_; |
339 }(); | 367 }(); |
340 memcpy(audio_buffer, play_buffer_.data(), play_buffer_.size()); | 368 memcpy(audio_buffer, play_buffer_.data(), play_buffer_.size()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 | 442 |
415 void AudioDeviceBuffer::ResetPlayStats() { | 443 void AudioDeviceBuffer::ResetPlayStats() { |
416 last_playout_time_ = rtc::TimeMillis(); | 444 last_playout_time_ = rtc::TimeMillis(); |
417 play_callbacks_ = 0; | 445 play_callbacks_ = 0; |
418 last_play_callbacks_ = 0; | 446 last_play_callbacks_ = 0; |
419 play_samples_ = 0; | 447 play_samples_ = 0; |
420 last_play_samples_ = 0; | 448 last_play_samples_ = 0; |
421 max_play_level_ = 0; | 449 max_play_level_ = 0; |
422 } | 450 } |
423 | 451 |
424 void AudioDeviceBuffer::UpdateRecStats(const void* audio_buffer, | 452 void AudioDeviceBuffer::UpdateRecStats(int16_t max_abs, size_t num_samples) { |
425 size_t num_samples) { | |
426 RTC_DCHECK(task_queue_.IsCurrent()); | 453 RTC_DCHECK(task_queue_.IsCurrent()); |
427 ++rec_callbacks_; | 454 ++rec_callbacks_; |
428 rec_samples_ += num_samples; | 455 rec_samples_ += num_samples; |
429 | 456 if (max_abs > max_rec_level_) { |
430 // Find the max absolute value in an audio packet twice per second and update | 457 max_rec_level_ = max_abs; |
431 // |max_rec_level_| to track the largest value. | |
432 if (rec_callbacks_ % 50 == 0) { | |
433 int16_t max_abs = WebRtcSpl_MaxAbsValueW16( | |
434 static_cast<int16_t*>(const_cast<void*>(audio_buffer)), | |
435 num_samples * rec_channels_); | |
436 if (max_abs > max_rec_level_) { | |
437 max_rec_level_ = max_abs; | |
438 } | |
439 } | 458 } |
440 } | 459 } |
441 | 460 |
442 void AudioDeviceBuffer::UpdatePlayStats(const void* audio_buffer, | 461 void AudioDeviceBuffer::UpdatePlayStats(int16_t max_abs, size_t num_samples) { |
443 size_t num_samples) { | |
444 RTC_DCHECK(task_queue_.IsCurrent()); | 462 RTC_DCHECK(task_queue_.IsCurrent()); |
445 ++play_callbacks_; | 463 ++play_callbacks_; |
446 play_samples_ += num_samples; | 464 play_samples_ += num_samples; |
447 | 465 if (max_abs > max_play_level_) { |
448 // Find the max absolute value in an audio packet twice per second and update | 466 max_play_level_ = max_abs; |
449 // |max_play_level_| to track the largest value. | |
450 if (play_callbacks_ % 50 == 0) { | |
451 int16_t max_abs = WebRtcSpl_MaxAbsValueW16( | |
452 static_cast<int16_t*>(const_cast<void*>(audio_buffer)), | |
453 num_samples * play_channels_); | |
454 if (max_abs > max_play_level_) { | |
455 max_play_level_ = max_abs; | |
456 } | |
457 } | 467 } |
458 } | 468 } |
459 | 469 |
460 } // namespace webrtc | 470 } // namespace webrtc |
OLD | NEW |