OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 : SoundDeviceLocator(name, device_name) { | 55 : SoundDeviceLocator(name, device_name) { |
56 // The ALSA descriptions have newlines in them, which won't show up in | 56 // The ALSA descriptions have newlines in them, which won't show up in |
57 // a drop-down box. Replace them with hyphens. | 57 // a drop-down box. Replace them with hyphens. |
58 rtc::replace_substrs(kAlsaDescriptionSearch, | 58 rtc::replace_substrs(kAlsaDescriptionSearch, |
59 sizeof(kAlsaDescriptionSearch) - 1, | 59 sizeof(kAlsaDescriptionSearch) - 1, |
60 kAlsaDescriptionReplace, | 60 kAlsaDescriptionReplace, |
61 sizeof(kAlsaDescriptionReplace) - 1, | 61 sizeof(kAlsaDescriptionReplace) - 1, |
62 &name_); | 62 &name_); |
63 } | 63 } |
64 | 64 |
65 virtual SoundDeviceLocator *Copy() const { | 65 SoundDeviceLocator *Copy() const override { |
66 return new AlsaDeviceLocator(*this); | 66 return new AlsaDeviceLocator(*this); |
67 } | 67 } |
68 }; | 68 }; |
69 | 69 |
70 // Functionality that is common to both AlsaInputStream and AlsaOutputStream. | 70 // Functionality that is common to both AlsaInputStream and AlsaOutputStream. |
71 class AlsaStream { | 71 class AlsaStream { |
72 public: | 72 public: |
73 AlsaStream(AlsaSoundSystem *alsa, | 73 AlsaStream(AlsaSoundSystem *alsa, |
74 snd_pcm_t *handle, | 74 snd_pcm_t *handle, |
75 size_t frame_size, | 75 size_t frame_size, |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 AlsaInputStream(AlsaSoundSystem *alsa, | 235 AlsaInputStream(AlsaSoundSystem *alsa, |
236 snd_pcm_t *handle, | 236 snd_pcm_t *handle, |
237 size_t frame_size, | 237 size_t frame_size, |
238 int wait_timeout_ms, | 238 int wait_timeout_ms, |
239 int flags, | 239 int flags, |
240 int freq) | 240 int freq) |
241 : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq), | 241 : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq), |
242 buffer_size_(0) { | 242 buffer_size_(0) { |
243 } | 243 } |
244 | 244 |
245 virtual ~AlsaInputStream() { | 245 ~AlsaInputStream() override { |
246 bool success = StopReading(); | 246 bool success = StopReading(); |
247 // We need that to live. | 247 // We need that to live. |
248 VERIFY(success); | 248 VERIFY(success); |
249 } | 249 } |
250 | 250 |
251 virtual bool StartReading() { | 251 bool StartReading() override { |
252 return StartWork(); | 252 return StartWork(); |
253 } | 253 } |
254 | 254 |
255 virtual bool StopReading() { | 255 bool StopReading() override { |
256 return StopWork(); | 256 return StopWork(); |
257 } | 257 } |
258 | 258 |
259 virtual bool GetVolume(int *volume) { | 259 bool GetVolume(int *volume) override { |
260 // TODO: Implement this. | 260 // TODO: Implement this. |
261 return false; | 261 return false; |
262 } | 262 } |
263 | 263 |
264 virtual bool SetVolume(int volume) { | 264 bool SetVolume(int volume) override { |
265 // TODO: Implement this. | 265 // TODO: Implement this. |
266 return false; | 266 return false; |
267 } | 267 } |
268 | 268 |
269 virtual bool Close() { | 269 bool Close() override { |
270 return StopReading() && stream_.Close(); | 270 return StopReading() && stream_.Close(); |
271 } | 271 } |
272 | 272 |
273 virtual int LatencyUsecs() { | 273 int LatencyUsecs() override { |
274 return stream_.CurrentDelayUsecs(); | 274 return stream_.CurrentDelayUsecs(); |
275 } | 275 } |
276 | 276 |
277 private: | 277 private: |
278 // Inherited from Worker. | 278 // Inherited from Worker. |
279 virtual void OnStart() { | 279 void OnStart() override { |
280 HaveWork(); | 280 HaveWork(); |
281 } | 281 } |
282 | 282 |
283 // Inherited from Worker. | 283 // Inherited from Worker. |
284 virtual void OnHaveWork() { | 284 void OnHaveWork() override { |
285 // Block waiting for data. | 285 // Block waiting for data. |
286 snd_pcm_uframes_t avail = stream_.Wait(); | 286 snd_pcm_uframes_t avail = stream_.Wait(); |
287 if (avail > 0) { | 287 if (avail > 0) { |
288 // Data is available. | 288 // Data is available. |
289 size_t size = avail * stream_.frame_size(); | 289 size_t size = avail * stream_.frame_size(); |
290 if (size > buffer_size_) { | 290 if (size > buffer_size_) { |
291 // Must increase buffer size. | 291 // Must increase buffer size. |
292 buffer_.reset(new char[size]); | 292 buffer_.reset(new char[size]); |
293 buffer_size_ = size; | 293 buffer_size_ = size; |
294 } | 294 } |
(...skipping 15 matching lines...) Expand all Loading... |
310 read * stream_.frame_size(), | 310 read * stream_.frame_size(), |
311 this); | 311 this); |
312 } | 312 } |
313 } | 313 } |
314 // Check for more data with no delay, after any pending messages are | 314 // Check for more data with no delay, after any pending messages are |
315 // dispatched. | 315 // dispatched. |
316 HaveWork(); | 316 HaveWork(); |
317 } | 317 } |
318 | 318 |
319 // Inherited from Worker. | 319 // Inherited from Worker. |
320 virtual void OnStop() { | 320 void OnStop() override { |
321 // Nothing to do. | 321 // Nothing to do. |
322 } | 322 } |
323 | 323 |
324 const char *GetError(int err) { | 324 const char *GetError(int err) { |
325 return stream_.GetError(err); | 325 return stream_.GetError(err); |
326 } | 326 } |
327 | 327 |
328 AlsaStream stream_; | 328 AlsaStream stream_; |
329 rtc::scoped_ptr<char[]> buffer_; | 329 rtc::scoped_ptr<char[]> buffer_; |
330 size_t buffer_size_; | 330 size_t buffer_size_; |
331 | 331 |
332 RTC_DISALLOW_COPY_AND_ASSIGN(AlsaInputStream); | 332 RTC_DISALLOW_COPY_AND_ASSIGN(AlsaInputStream); |
333 }; | 333 }; |
334 | 334 |
335 // Implementation of an output stream. See soundoutputstreaminterface.h | 335 // Implementation of an output stream. See soundoutputstreaminterface.h |
336 // regarding thread-safety. | 336 // regarding thread-safety. |
337 class AlsaOutputStream : | 337 class AlsaOutputStream : public SoundOutputStreamInterface, |
338 public SoundOutputStreamInterface, | 338 private rtc::Worker { |
339 private rtc::Worker { | |
340 public: | 339 public: |
341 AlsaOutputStream(AlsaSoundSystem *alsa, | 340 AlsaOutputStream(AlsaSoundSystem *alsa, |
342 snd_pcm_t *handle, | 341 snd_pcm_t *handle, |
343 size_t frame_size, | 342 size_t frame_size, |
344 int wait_timeout_ms, | 343 int wait_timeout_ms, |
345 int flags, | 344 int flags, |
346 int freq) | 345 int freq) |
347 : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq) { | 346 : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq) { |
348 } | 347 } |
349 | 348 |
350 virtual ~AlsaOutputStream() { | 349 ~AlsaOutputStream() override { |
351 bool success = DisableBufferMonitoring(); | 350 bool success = DisableBufferMonitoring(); |
352 // We need that to live. | 351 // We need that to live. |
353 VERIFY(success); | 352 VERIFY(success); |
354 } | 353 } |
355 | 354 |
356 virtual bool EnableBufferMonitoring() { | 355 bool EnableBufferMonitoring() override { |
357 return StartWork(); | 356 return StartWork(); |
358 } | 357 } |
359 | 358 |
360 virtual bool DisableBufferMonitoring() { | 359 bool DisableBufferMonitoring() override { |
361 return StopWork(); | 360 return StopWork(); |
362 } | 361 } |
363 | 362 |
364 virtual bool WriteSamples(const void *sample_data, | 363 bool WriteSamples(const void *sample_data, size_t size) override { |
365 size_t size) { | |
366 if (size % stream_.frame_size() != 0) { | 364 if (size % stream_.frame_size() != 0) { |
367 // No client of SoundSystemInterface does this, so let's not support it. | 365 // No client of SoundSystemInterface does this, so let's not support it. |
368 // (If we wanted to support it, we'd basically just buffer the fractional | 366 // (If we wanted to support it, we'd basically just buffer the fractional |
369 // frame until we get more data.) | 367 // frame until we get more data.) |
370 ASSERT(false); | 368 ASSERT(false); |
371 LOG(LS_ERROR) << "Writes with fractional frames are not supported"; | 369 LOG(LS_ERROR) << "Writes with fractional frames are not supported"; |
372 return false; | 370 return false; |
373 } | 371 } |
374 snd_pcm_uframes_t frames = size / stream_.frame_size(); | 372 snd_pcm_uframes_t frames = size / stream_.frame_size(); |
375 snd_pcm_sframes_t written = stream_.symbol_table()->snd_pcm_writei()( | 373 snd_pcm_sframes_t written = stream_.symbol_table()->snd_pcm_writei()( |
376 stream_.handle(), | 374 stream_.handle(), |
377 sample_data, | 375 sample_data, |
378 frames); | 376 frames); |
379 if (written < 0) { | 377 if (written < 0) { |
380 LOG(LS_ERROR) << "snd_pcm_writei(): " << GetError(written); | 378 LOG(LS_ERROR) << "snd_pcm_writei(): " << GetError(written); |
381 stream_.Recover(written); | 379 stream_.Recover(written); |
382 return false; | 380 return false; |
383 } else if (static_cast<snd_pcm_uframes_t>(written) < frames) { | 381 } else if (static_cast<snd_pcm_uframes_t>(written) < frames) { |
384 // Shouldn't happen. Drop the rest of the data. | 382 // Shouldn't happen. Drop the rest of the data. |
385 LOG(LS_ERROR) << "Stream wrote only " << written << " of " << frames | 383 LOG(LS_ERROR) << "Stream wrote only " << written << " of " << frames |
386 << " frames!"; | 384 << " frames!"; |
387 return false; | 385 return false; |
388 } | 386 } |
389 return true; | 387 return true; |
390 } | 388 } |
391 | 389 |
392 virtual bool GetVolume(int *volume) { | 390 bool GetVolume(int *volume) override { |
393 // TODO: Implement this. | 391 // TODO: Implement this. |
394 return false; | 392 return false; |
395 } | 393 } |
396 | 394 |
397 virtual bool SetVolume(int volume) { | 395 bool SetVolume(int volume) override { |
398 // TODO: Implement this. | 396 // TODO: Implement this. |
399 return false; | 397 return false; |
400 } | 398 } |
401 | 399 |
402 virtual bool Close() { | 400 bool Close() override { |
403 return DisableBufferMonitoring() && stream_.Close(); | 401 return DisableBufferMonitoring() && stream_.Close(); |
404 } | 402 } |
405 | 403 |
406 virtual int LatencyUsecs() { | 404 int LatencyUsecs() override { |
407 return stream_.CurrentDelayUsecs(); | 405 return stream_.CurrentDelayUsecs(); |
408 } | 406 } |
409 | 407 |
410 private: | 408 private: |
411 // Inherited from Worker. | 409 // Inherited from Worker. |
412 virtual void OnStart() { | 410 void OnStart() override { |
413 HaveWork(); | 411 HaveWork(); |
414 } | 412 } |
415 | 413 |
416 // Inherited from Worker. | 414 // Inherited from Worker. |
417 virtual void OnHaveWork() { | 415 void OnHaveWork() override { |
418 snd_pcm_uframes_t avail = stream_.Wait(); | 416 snd_pcm_uframes_t avail = stream_.Wait(); |
419 if (avail > 0) { | 417 if (avail > 0) { |
420 size_t space = avail * stream_.frame_size(); | 418 size_t space = avail * stream_.frame_size(); |
421 SignalBufferSpace(space, this); | 419 SignalBufferSpace(space, this); |
422 } | 420 } |
423 HaveWork(); | 421 HaveWork(); |
424 } | 422 } |
425 | 423 |
426 // Inherited from Worker. | 424 // Inherited from Worker. |
427 virtual void OnStop() { | 425 void OnStop() override { |
428 // Nothing to do. | 426 // Nothing to do. |
429 } | 427 } |
430 | 428 |
431 const char *GetError(int err) { | 429 const char *GetError(int err) { |
432 return stream_.GetError(err); | 430 return stream_.GetError(err); |
433 } | 431 } |
434 | 432 |
435 AlsaStream stream_; | 433 AlsaStream stream_; |
436 | 434 |
437 RTC_DISALLOW_COPY_AND_ASSIGN(AlsaOutputStream); | 435 RTC_DISALLOW_COPY_AND_ASSIGN(AlsaOutputStream); |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 } | 734 } |
737 return new AlsaInputStream( | 735 return new AlsaInputStream( |
738 this, handle, frame_size, wait_timeout_ms, flags, freq); | 736 this, handle, frame_size, wait_timeout_ms, flags, freq); |
739 } | 737 } |
740 | 738 |
741 inline const char *AlsaSoundSystem::GetError(int err) { | 739 inline const char *AlsaSoundSystem::GetError(int err) { |
742 return symbol_table_.snd_strerror()(err); | 740 return symbol_table_.snd_strerror()(err); |
743 } | 741 } |
744 | 742 |
745 } // namespace rtc | 743 } // namespace rtc |
OLD | NEW |