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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 rec_callbacks_(0), | 54 rec_callbacks_(0), |
55 last_rec_callbacks_(0), | 55 last_rec_callbacks_(0), |
56 play_callbacks_(0), | 56 play_callbacks_(0), |
57 last_play_callbacks_(0), | 57 last_play_callbacks_(0), |
58 rec_samples_(0), | 58 rec_samples_(0), |
59 last_rec_samples_(0), | 59 last_rec_samples_(0), |
60 play_samples_(0), | 60 play_samples_(0), |
61 last_play_samples_(0), | 61 last_play_samples_(0), |
62 last_log_stat_time_(0) { | 62 last_log_stat_time_(0) { |
63 LOG(INFO) << "AudioDeviceBuffer::ctor"; | 63 LOG(INFO) << "AudioDeviceBuffer::ctor"; |
64 // TODO(henrika): improve buffer handling and ensure that we don't allocate | |
65 // more than what is required. | |
66 play_buffer_.reset(new int8_t[kMaxBufferSizeBytes]); | |
67 rec_buffer_.reset(new int8_t[kMaxBufferSizeBytes]); | |
64 } | 68 } |
65 | 69 |
66 AudioDeviceBuffer::~AudioDeviceBuffer() { | 70 AudioDeviceBuffer::~AudioDeviceBuffer() { |
67 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 71 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
68 LOG(INFO) << "AudioDeviceBuffer::~dtor"; | 72 LOG(INFO) << "AudioDeviceBuffer::~dtor"; |
69 | 73 |
70 size_t total_diff_time = 0; | 74 size_t total_diff_time = 0; |
71 int num_measurements = 0; | 75 int num_measurements = 0; |
72 LOG(INFO) << "[playout diff time => #measurements]"; | 76 LOG(INFO) << "[playout diff time => #measurements]"; |
73 for (size_t diff = 0; diff < arraysize(playout_diff_times_); ++diff) { | 77 for (size_t diff = 0; diff < arraysize(playout_diff_times_); ++diff) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 return 0; | 232 return 0; |
229 } | 233 } |
230 | 234 |
231 int32_t AudioDeviceBuffer::StopOutputFileRecording() { | 235 int32_t AudioDeviceBuffer::StopOutputFileRecording() { |
232 LOG(LS_WARNING) << "Not implemented"; | 236 LOG(LS_WARNING) << "Not implemented"; |
233 return 0; | 237 return 0; |
234 } | 238 } |
235 | 239 |
236 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, | 240 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, |
237 size_t num_samples) { | 241 size_t num_samples) { |
238 AllocateRecordingBufferIfNeeded(); | 242 UpdateRecordingParameters(); |
239 RTC_CHECK(rec_buffer_); | |
240 // WebRTC can only receive audio in 10ms chunks, hence we fail if the native | 243 // WebRTC can only receive audio in 10ms chunks, hence we fail if the native |
241 // audio layer tries to deliver something else. | 244 // audio layer tries to deliver something else. |
242 RTC_CHECK_EQ(num_samples, rec_samples_per_10ms_); | 245 RTC_CHECK_EQ(num_samples, rec_samples_per_10ms_); |
243 | 246 |
244 rtc::CritScope lock(&_critSect); | 247 rtc::CritScope lock(&_critSect); |
245 | 248 |
246 if (rec_channel_ == AudioDeviceModule::kChannelBoth) { | 249 if (rec_channel_ == AudioDeviceModule::kChannelBoth) { |
247 // Copy the complete input buffer to the local buffer. | 250 // Copy the complete input buffer to the local buffer. |
248 memcpy(&rec_buffer_[0], audio_buffer, rec_bytes_per_10ms_); | 251 memcpy(&rec_buffer_[0], audio_buffer, rec_bytes_per_10ms_); |
249 } else { | 252 } else { |
(...skipping 12 matching lines...) Expand all Loading... | |
262 } | 265 } |
263 | 266 |
264 // Update some stats but do it on the task queue to ensure that the members | 267 // Update some stats but do it on the task queue to ensure that the members |
265 // are modified and read on the same thread. | 268 // are modified and read on the same thread. |
266 task_queue_.PostTask( | 269 task_queue_.PostTask( |
267 rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, num_samples)); | 270 rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, num_samples)); |
268 return 0; | 271 return 0; |
269 } | 272 } |
270 | 273 |
271 int32_t AudioDeviceBuffer::DeliverRecordedData() { | 274 int32_t AudioDeviceBuffer::DeliverRecordedData() { |
272 RTC_CHECK(rec_buffer_); | |
273 RTC_DCHECK(audio_transport_cb_); | 275 RTC_DCHECK(audio_transport_cb_); |
274 rtc::CritScope lock(&_critSectCb); | 276 rtc::CritScope lock(&_critSectCb); |
275 | 277 |
276 if (!audio_transport_cb_) { | 278 if (!audio_transport_cb_) { |
277 LOG(LS_WARNING) << "Invalid audio transport"; | 279 LOG(LS_WARNING) << "Invalid audio transport"; |
278 return 0; | 280 return 0; |
279 } | 281 } |
280 | 282 |
281 int32_t res(0); | 283 int32_t res(0); |
282 uint32_t newMicLevel(0); | 284 uint32_t newMicLevel(0); |
(...skipping 16 matching lines...) Expand all Loading... | |
299 // position/index corresponds to time differences (in milliseconds) between | 301 // position/index corresponds to time differences (in milliseconds) between |
300 // two successive playout callbacks, and the stored value is the number of | 302 // two successive playout callbacks, and the stored value is the number of |
301 // times a given time difference was found. | 303 // times a given time difference was found. |
302 int64_t now_time = rtc::TimeMillis(); | 304 int64_t now_time = rtc::TimeMillis(); |
303 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_); | 305 size_t diff_time = rtc::TimeDiff(now_time, last_playout_time_); |
304 // Truncate at 500ms to limit the size of the array. | 306 // Truncate at 500ms to limit the size of the array. |
305 diff_time = std::min(kMaxDeltaTimeInMs, diff_time); | 307 diff_time = std::min(kMaxDeltaTimeInMs, diff_time); |
306 last_playout_time_ = now_time; | 308 last_playout_time_ = now_time; |
307 playout_diff_times_[diff_time]++; | 309 playout_diff_times_[diff_time]++; |
308 | 310 |
309 AllocatePlayoutBufferIfNeeded(); | 311 UpdatePlayoutParameters(); |
310 RTC_CHECK(play_buffer_); | |
311 // WebRTC can only provide audio in 10ms chunks, hence we fail if the native | 312 // WebRTC can only provide audio in 10ms chunks, hence we fail if the native |
312 // audio layer asks for something else. | 313 // audio layer asks for something else. |
313 RTC_CHECK_EQ(num_samples, play_samples_per_10ms_); | 314 RTC_CHECK_EQ(num_samples, play_samples_per_10ms_); |
314 | 315 |
315 rtc::CritScope lock(&_critSectCb); | 316 rtc::CritScope lock(&_critSectCb); |
316 | 317 |
317 // It is currently supported to start playout without a valid audio | 318 // It is currently supported to start playout without a valid audio |
318 // transport object. Leads to warning and silence. | 319 // transport object. Leads to warning and silence. |
319 if (!audio_transport_cb_) { | 320 if (!audio_transport_cb_) { |
320 LOG(LS_WARNING) << "Invalid audio transport"; | 321 LOG(LS_WARNING) << "Invalid audio transport"; |
(...skipping 18 matching lines...) Expand all Loading... | |
339 rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, num_samples_out)); | 340 rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, num_samples_out)); |
340 return static_cast<int32_t>(num_samples_out); | 341 return static_cast<int32_t>(num_samples_out); |
341 } | 342 } |
342 | 343 |
343 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { | 344 int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { |
344 rtc::CritScope lock(&_critSect); | 345 rtc::CritScope lock(&_critSect); |
345 memcpy(audio_buffer, &play_buffer_[0], play_bytes_per_10ms_); | 346 memcpy(audio_buffer, &play_buffer_[0], play_bytes_per_10ms_); |
346 return static_cast<int32_t>(play_samples_per_10ms_); | 347 return static_cast<int32_t>(play_samples_per_10ms_); |
347 } | 348 } |
348 | 349 |
349 void AudioDeviceBuffer::AllocatePlayoutBufferIfNeeded() { | 350 void AudioDeviceBuffer::UpdatePlayoutParameters() { |
350 RTC_CHECK(play_bytes_per_sample_); | 351 RTC_CHECK(play_bytes_per_sample_); |
351 if (play_buffer_) | |
352 return; | |
353 LOG(INFO) << __FUNCTION__; | |
354 rtc::CritScope lock(&_critSect); | 352 rtc::CritScope lock(&_critSect); |
355 // Derive the required buffer size given sample rate and number of channels. | 353 // Update the required buffer size given sample rate and number of channels. |
356 play_samples_per_10ms_ = static_cast<size_t>(play_sample_rate_ * 10 / 1000); | 354 play_samples_per_10ms_ = static_cast<size_t>(play_sample_rate_ * 10 / 1000); |
357 play_bytes_per_10ms_ = play_bytes_per_sample_ * play_samples_per_10ms_; | 355 play_bytes_per_10ms_ = play_bytes_per_sample_ * play_samples_per_10ms_; |
358 LOG(INFO) << "playout samples per 10ms: " << play_samples_per_10ms_; | 356 RTC_DCHECK_LE(play_bytes_per_10ms_, kMaxBufferSizeBytes); |
Henrik Grunell WebRTC
2016/09/09 10:19:29
Nit: I think it should even be a CHECK (not DCHECK
| |
359 LOG(INFO) << "playout bytes per 10ms: " << play_bytes_per_10ms_; | |
360 // Allocate memory for the playout audio buffer. It will always contain audio | |
361 // samples corresponding to 10ms of audio to be played out. | |
362 play_buffer_.reset(new int8_t[play_bytes_per_10ms_]); | |
363 } | 357 } |
364 | 358 |
365 void AudioDeviceBuffer::AllocateRecordingBufferIfNeeded() { | 359 void AudioDeviceBuffer::UpdateRecordingParameters() { |
366 RTC_CHECK(rec_bytes_per_sample_); | 360 RTC_CHECK(rec_bytes_per_sample_); |
367 if (rec_buffer_) | |
368 return; | |
369 LOG(INFO) << __FUNCTION__; | |
370 rtc::CritScope lock(&_critSect); | 361 rtc::CritScope lock(&_critSect); |
371 // Derive the required buffer size given sample rate and number of channels. | 362 // Update the required buffer size given sample rate and number of channels. |
372 rec_samples_per_10ms_ = static_cast<size_t>(rec_sample_rate_ * 10 / 1000); | 363 rec_samples_per_10ms_ = static_cast<size_t>(rec_sample_rate_ * 10 / 1000); |
373 rec_bytes_per_10ms_ = rec_bytes_per_sample_ * rec_samples_per_10ms_; | 364 rec_bytes_per_10ms_ = rec_bytes_per_sample_ * rec_samples_per_10ms_; |
374 LOG(INFO) << "recorded samples per 10ms: " << rec_samples_per_10ms_; | 365 RTC_DCHECK_LE(rec_bytes_per_10ms_, kMaxBufferSizeBytes); |
375 LOG(INFO) << "recorded bytes per 10ms: " << rec_bytes_per_10ms_; | |
376 // Allocate memory for the recording audio buffer. It will always contain | |
377 // audio samples corresponding to 10ms of audio. | |
378 rec_buffer_.reset(new int8_t[rec_bytes_per_10ms_]); | |
379 } | 366 } |
380 | 367 |
381 void AudioDeviceBuffer::StartTimer() { | 368 void AudioDeviceBuffer::StartTimer() { |
382 last_log_stat_time_ = rtc::TimeMillis(); | 369 last_log_stat_time_ = rtc::TimeMillis(); |
383 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this), | 370 task_queue_.PostDelayedTask(rtc::Bind(&AudioDeviceBuffer::LogStats, this), |
384 kTimerIntervalInMilliseconds); | 371 kTimerIntervalInMilliseconds); |
385 } | 372 } |
386 | 373 |
387 void AudioDeviceBuffer::LogStats() { | 374 void AudioDeviceBuffer::LogStats() { |
388 RTC_DCHECK(task_queue_.IsCurrent()); | 375 RTC_DCHECK(task_queue_.IsCurrent()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 rec_samples_ += num_samples; | 422 rec_samples_ += num_samples; |
436 } | 423 } |
437 | 424 |
438 void AudioDeviceBuffer::UpdatePlayStats(size_t num_samples) { | 425 void AudioDeviceBuffer::UpdatePlayStats(size_t num_samples) { |
439 RTC_DCHECK(task_queue_.IsCurrent()); | 426 RTC_DCHECK(task_queue_.IsCurrent()); |
440 ++play_callbacks_; | 427 ++play_callbacks_; |
441 play_samples_ += num_samples; | 428 play_samples_ += num_samples; |
442 } | 429 } |
443 | 430 |
444 } // namespace webrtc | 431 } // namespace webrtc |
OLD | NEW |