blob: 779641dc81d74c978c7fb23a433b913732e00b2e [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org20aabbb2012-02-20 09:17:41 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "trace.h"
12#include "critical_section_wrapper.h"
13#include "audio_device_buffer.h"
14#include "audio_device_utility.h"
15#include "audio_device_config.h"
16
17#include <stdlib.h>
18#include <string.h>
19#include <cassert>
20
21#include "signal_processing_library.h"
22
23namespace webrtc {
24
25// ----------------------------------------------------------------------------
26// ctor
27// ----------------------------------------------------------------------------
28
29AudioDeviceBuffer::AudioDeviceBuffer() :
30 _id(-1),
31 _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
32 _critSectCb(*CriticalSectionWrapper::CreateCriticalSection()),
33 _ptrCbAudioTransport(NULL),
34 _recSampleRate(0),
35 _playSampleRate(0),
36 _recChannels(0),
37 _playChannels(0),
38 _recChannel(AudioDeviceModule::kChannelBoth),
39 _recBytesPerSample(0),
40 _playBytesPerSample(0),
41 _recSamples(0),
niklase@google.com470e71d2011-07-07 08:21:25 +000042 _recSize(0),
xians@google.com88bd4402011-08-04 15:33:30 +000043 _playSamples(0),
niklase@google.com470e71d2011-07-07 08:21:25 +000044 _playSize(0),
45 _recFile(*FileWrapper::Create()),
46 _playFile(*FileWrapper::Create()),
niklase@google.com470e71d2011-07-07 08:21:25 +000047 _currentMicLevel(0),
xians@google.com88bd4402011-08-04 15:33:30 +000048 _newMicLevel(0),
niklas.enbom@webrtc.org3be565b2013-05-07 21:04:24 +000049 _typingStatus(false),
niklase@google.com470e71d2011-07-07 08:21:25 +000050 _playDelayMS(0),
51 _recDelayMS(0),
xians@webrtc.org233c58d2013-05-06 11:52:47 +000052 _clockDrift(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000053 // valid ID will be set later by SetId, use -1 for now
54 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s created", __FUNCTION__);
xians@webrtc.orgeff3c892011-12-06 10:02:56 +000055 memset(_recBuffer, 0, kMaxBufferSizeBytes);
56 memset(_playBuffer, 0, kMaxBufferSizeBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +000057}
58
59// ----------------------------------------------------------------------------
60// dtor
61// ----------------------------------------------------------------------------
62
63AudioDeviceBuffer::~AudioDeviceBuffer()
64{
65 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__);
66 {
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +000067 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000068
69 _recFile.Flush();
70 _recFile.CloseFile();
71 delete &_recFile;
72
73 _playFile.Flush();
74 _playFile.CloseFile();
75 delete &_playFile;
niklase@google.com470e71d2011-07-07 08:21:25 +000076 }
77
78 delete &_critSect;
79 delete &_critSectCb;
80}
81
82// ----------------------------------------------------------------------------
83// SetId
84// ----------------------------------------------------------------------------
85
pbos@webrtc.org25509882013-04-09 10:30:35 +000086void AudioDeviceBuffer::SetId(uint32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000087{
88 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "AudioDeviceBuffer::SetId(id=%d)", id);
89 _id = id;
90}
91
92// ----------------------------------------------------------------------------
93// RegisterAudioCallback
94// ----------------------------------------------------------------------------
95
pbos@webrtc.org25509882013-04-09 10:30:35 +000096int32_t AudioDeviceBuffer::RegisterAudioCallback(AudioTransport* audioCallback)
niklase@google.com470e71d2011-07-07 08:21:25 +000097{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +000098 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +000099 _ptrCbAudioTransport = audioCallback;
100
101 return 0;
102}
103
104// ----------------------------------------------------------------------------
105// InitPlayout
106// ----------------------------------------------------------------------------
107
pbos@webrtc.org25509882013-04-09 10:30:35 +0000108int32_t AudioDeviceBuffer::InitPlayout()
niklase@google.com470e71d2011-07-07 08:21:25 +0000109{
110 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 return 0;
112}
113
114// ----------------------------------------------------------------------------
115// InitRecording
116// ----------------------------------------------------------------------------
117
pbos@webrtc.org25509882013-04-09 10:30:35 +0000118int32_t AudioDeviceBuffer::InitRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000119{
120 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000121 return 0;
122}
123
124// ----------------------------------------------------------------------------
125// SetRecordingSampleRate
126// ----------------------------------------------------------------------------
127
pbos@webrtc.org25509882013-04-09 10:30:35 +0000128int32_t AudioDeviceBuffer::SetRecordingSampleRate(uint32_t fsHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000129{
130 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetRecordingSampleRate(fsHz=%u)", fsHz);
131
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000132 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 _recSampleRate = fsHz;
134 return 0;
135}
136
137// ----------------------------------------------------------------------------
138// SetPlayoutSampleRate
139// ----------------------------------------------------------------------------
140
pbos@webrtc.org25509882013-04-09 10:30:35 +0000141int32_t AudioDeviceBuffer::SetPlayoutSampleRate(uint32_t fsHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000142{
143 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetPlayoutSampleRate(fsHz=%u)", fsHz);
144
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000145 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 _playSampleRate = fsHz;
147 return 0;
148}
149
150// ----------------------------------------------------------------------------
151// RecordingSampleRate
152// ----------------------------------------------------------------------------
153
pbos@webrtc.org25509882013-04-09 10:30:35 +0000154int32_t AudioDeviceBuffer::RecordingSampleRate() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000155{
156 return _recSampleRate;
157}
158
159// ----------------------------------------------------------------------------
160// PlayoutSampleRate
161// ----------------------------------------------------------------------------
162
pbos@webrtc.org25509882013-04-09 10:30:35 +0000163int32_t AudioDeviceBuffer::PlayoutSampleRate() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000164{
165 return _playSampleRate;
166}
167
168// ----------------------------------------------------------------------------
169// SetRecordingChannels
170// ----------------------------------------------------------------------------
171
pbos@webrtc.org25509882013-04-09 10:30:35 +0000172int32_t AudioDeviceBuffer::SetRecordingChannels(uint8_t channels)
niklase@google.com470e71d2011-07-07 08:21:25 +0000173{
174 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetRecordingChannels(channels=%u)", channels);
175
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000176 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000177 _recChannels = channels;
178 _recBytesPerSample = 2*channels; // 16 bits per sample in mono, 32 bits in stereo
179 return 0;
180}
181
182// ----------------------------------------------------------------------------
183// SetPlayoutChannels
184// ----------------------------------------------------------------------------
185
pbos@webrtc.org25509882013-04-09 10:30:35 +0000186int32_t AudioDeviceBuffer::SetPlayoutChannels(uint8_t channels)
niklase@google.com470e71d2011-07-07 08:21:25 +0000187{
188 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetPlayoutChannels(channels=%u)", channels);
189
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000190 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000191 _playChannels = channels;
192 // 16 bits per sample in mono, 32 bits in stereo
193 _playBytesPerSample = 2*channels;
194 return 0;
195}
196
197// ----------------------------------------------------------------------------
198// SetRecordingChannel
199//
200// Select which channel to use while recording.
201// This API requires that stereo is enabled.
202//
203// Note that, the nChannel parameter in RecordedDataIsAvailable will be
204// set to 2 even for kChannelLeft and kChannelRight. However, nBytesPerSample
205// will be 2 instead of 4 four these cases.
206// ----------------------------------------------------------------------------
207
pbos@webrtc.org25509882013-04-09 10:30:35 +0000208int32_t AudioDeviceBuffer::SetRecordingChannel(const AudioDeviceModule::ChannelType channel)
niklase@google.com470e71d2011-07-07 08:21:25 +0000209{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000210 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000211
212 if (_recChannels == 1)
213 {
214 return -1;
215 }
216
217 if (channel == AudioDeviceModule::kChannelBoth)
218 {
219 // two bytes per channel
220 _recBytesPerSample = 4;
221 }
222 else
223 {
224 // only utilize one out of two possible channels (left or right)
225 _recBytesPerSample = 2;
226 }
227 _recChannel = channel;
228
229 return 0;
230}
231
232// ----------------------------------------------------------------------------
233// RecordingChannel
234// ----------------------------------------------------------------------------
235
pbos@webrtc.org25509882013-04-09 10:30:35 +0000236int32_t AudioDeviceBuffer::RecordingChannel(AudioDeviceModule::ChannelType& channel) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000237{
238 channel = _recChannel;
239 return 0;
240}
241
242// ----------------------------------------------------------------------------
243// RecordingChannels
244// ----------------------------------------------------------------------------
245
pbos@webrtc.org25509882013-04-09 10:30:35 +0000246uint8_t AudioDeviceBuffer::RecordingChannels() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000247{
248 return _recChannels;
249}
250
251// ----------------------------------------------------------------------------
252// PlayoutChannels
253// ----------------------------------------------------------------------------
254
pbos@webrtc.org25509882013-04-09 10:30:35 +0000255uint8_t AudioDeviceBuffer::PlayoutChannels() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000256{
257 return _playChannels;
258}
259
260// ----------------------------------------------------------------------------
261// SetCurrentMicLevel
262// ----------------------------------------------------------------------------
263
pbos@webrtc.org25509882013-04-09 10:30:35 +0000264int32_t AudioDeviceBuffer::SetCurrentMicLevel(uint32_t level)
niklase@google.com470e71d2011-07-07 08:21:25 +0000265{
266 _currentMicLevel = level;
267 return 0;
268}
269
niklas.enbom@webrtc.org3be565b2013-05-07 21:04:24 +0000270int32_t AudioDeviceBuffer::SetTypingStatus(bool typingStatus)
271{
272 _typingStatus = typingStatus;
273 return 0;
274}
275
niklase@google.com470e71d2011-07-07 08:21:25 +0000276// ----------------------------------------------------------------------------
277// NewMicLevel
278// ----------------------------------------------------------------------------
279
pbos@webrtc.org25509882013-04-09 10:30:35 +0000280uint32_t AudioDeviceBuffer::NewMicLevel() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000281{
282 return _newMicLevel;
283}
284
285// ----------------------------------------------------------------------------
286// SetVQEData
287// ----------------------------------------------------------------------------
288
pbos@webrtc.org25509882013-04-09 10:30:35 +0000289int32_t AudioDeviceBuffer::SetVQEData(uint32_t playDelayMS, uint32_t recDelayMS, int32_t clockDrift)
niklase@google.com470e71d2011-07-07 08:21:25 +0000290{
291 if ((playDelayMS + recDelayMS) > 300)
292 {
293 WEBRTC_TRACE(kTraceWarning, kTraceUtility, _id, "too long delay (play:%i rec:%i)", playDelayMS, recDelayMS, clockDrift);
294 }
295
296 _playDelayMS = playDelayMS;
297 _recDelayMS = recDelayMS;
298 _clockDrift = clockDrift;
299
300 return 0;
301}
302
303// ----------------------------------------------------------------------------
304// StartInputFileRecording
305// ----------------------------------------------------------------------------
306
pbos@webrtc.org25509882013-04-09 10:30:35 +0000307int32_t AudioDeviceBuffer::StartInputFileRecording(
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000308 const char fileName[kAdmMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000309{
310 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
311
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000312 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000313
314 _recFile.Flush();
315 _recFile.CloseFile();
316
317 return (_recFile.OpenFile(fileName, false, false, false));
318}
319
320// ----------------------------------------------------------------------------
321// StopInputFileRecording
322// ----------------------------------------------------------------------------
323
pbos@webrtc.org25509882013-04-09 10:30:35 +0000324int32_t AudioDeviceBuffer::StopInputFileRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000325{
326 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
327
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000328 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000329
330 _recFile.Flush();
331 _recFile.CloseFile();
332
333 return 0;
334}
335
336// ----------------------------------------------------------------------------
337// StartOutputFileRecording
338// ----------------------------------------------------------------------------
339
pbos@webrtc.org25509882013-04-09 10:30:35 +0000340int32_t AudioDeviceBuffer::StartOutputFileRecording(
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000341 const char fileName[kAdmMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000342{
343 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
344
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000345 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000346
347 _playFile.Flush();
348 _playFile.CloseFile();
349
350 return (_playFile.OpenFile(fileName, false, false, false));
351}
352
353// ----------------------------------------------------------------------------
354// StopOutputFileRecording
355// ----------------------------------------------------------------------------
356
pbos@webrtc.org25509882013-04-09 10:30:35 +0000357int32_t AudioDeviceBuffer::StopOutputFileRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000358{
359 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
360
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000361 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000362
363 _playFile.Flush();
364 _playFile.CloseFile();
365
366 return 0;
367}
368
369// ----------------------------------------------------------------------------
370// SetRecordedBuffer
371//
372// Store recorded audio buffer in local memory ready for the actual
373// "delivery" using a callback.
374//
375// This method can also parse out left or right channel from a stereo
376// input signal, i.e., emulate mono.
377//
378// Examples:
379//
380// 16-bit,48kHz mono, 10ms => nSamples=480 => _recSize=2*480=960 bytes
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000381// 16-bit,48kHz stereo,10ms => nSamples=480 => _recSize=4*480=1920 bytes
niklase@google.com470e71d2011-07-07 08:21:25 +0000382// ----------------------------------------------------------------------------
383
pbos@webrtc.org25509882013-04-09 10:30:35 +0000384int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audioBuffer,
385 uint32_t nSamples)
niklase@google.com470e71d2011-07-07 08:21:25 +0000386{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000387 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000388
389 if (_recBytesPerSample == 0)
390 {
391 assert(false);
392 return -1;
393 }
394
395 _recSamples = nSamples;
396 _recSize = _recBytesPerSample*nSamples; // {2,4}*nSamples
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000397 if (_recSize > kMaxBufferSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000398 {
399 assert(false);
400 return -1;
401 }
402
403 if (nSamples != _recSamples)
404 {
405 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "invalid number of recorded samples (%d)", nSamples);
406 return -1;
407 }
408
409 if (_recChannel == AudioDeviceModule::kChannelBoth)
410 {
411 // (default) copy the complete input buffer to the local buffer
412 memcpy(&_recBuffer[0], audioBuffer, _recSize);
413 }
414 else
415 {
pbos@webrtc.org25509882013-04-09 10:30:35 +0000416 int16_t* ptr16In = (int16_t*)audioBuffer;
417 int16_t* ptr16Out = (int16_t*)&_recBuffer[0];
niklase@google.com470e71d2011-07-07 08:21:25 +0000418
419 if (AudioDeviceModule::kChannelRight == _recChannel)
420 {
421 ptr16In++;
422 }
423
424 // exctract left or right channel from input buffer to the local buffer
pbos@webrtc.org25509882013-04-09 10:30:35 +0000425 for (uint32_t i = 0; i < _recSamples; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000426 {
427 *ptr16Out = *ptr16In;
428 ptr16Out++;
429 ptr16In++;
430 ptr16In++;
431 }
432 }
433
434 if (_recFile.Open())
435 {
436 // write to binary file in mono or stereo (interleaved)
437 _recFile.Write(&_recBuffer[0], _recSize);
438 }
439
440 return 0;
441}
442
443// ----------------------------------------------------------------------------
444// DeliverRecordedData
445// ----------------------------------------------------------------------------
446
pbos@webrtc.org25509882013-04-09 10:30:35 +0000447int32_t AudioDeviceBuffer::DeliverRecordedData()
niklase@google.com470e71d2011-07-07 08:21:25 +0000448{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000449 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +0000450
451 // Ensure that user has initialized all essential members
452 if ((_recSampleRate == 0) ||
453 (_recSamples == 0) ||
454 (_recBytesPerSample == 0) ||
455 (_recChannels == 0))
456 {
457 assert(false);
458 return -1;
459 }
460
461 if (_ptrCbAudioTransport == NULL)
462 {
463 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to deliver recorded data (AudioTransport does not exist)");
464 return 0;
465 }
466
pbos@webrtc.org25509882013-04-09 10:30:35 +0000467 int32_t res(0);
468 uint32_t newMicLevel(0);
469 uint32_t totalDelayMS = _playDelayMS +_recDelayMS;
niklase@google.com470e71d2011-07-07 08:21:25 +0000470
niklase@google.com470e71d2011-07-07 08:21:25 +0000471 res = _ptrCbAudioTransport->RecordedDataIsAvailable(&_recBuffer[0],
472 _recSamples,
473 _recBytesPerSample,
474 _recChannels,
475 _recSampleRate,
476 totalDelayMS,
477 _clockDrift,
478 _currentMicLevel,
niklas.enbom@webrtc.org3be565b2013-05-07 21:04:24 +0000479 _typingStatus,
niklase@google.com470e71d2011-07-07 08:21:25 +0000480 newMicLevel);
481 if (res != -1)
482 {
483 _newMicLevel = newMicLevel;
484 }
485
486 return 0;
487}
488
489// ----------------------------------------------------------------------------
490// RequestPlayoutData
491// ----------------------------------------------------------------------------
492
pbos@webrtc.org25509882013-04-09 10:30:35 +0000493int32_t AudioDeviceBuffer::RequestPlayoutData(uint32_t nSamples)
niklase@google.com470e71d2011-07-07 08:21:25 +0000494{
pbos@webrtc.org25509882013-04-09 10:30:35 +0000495 uint32_t playSampleRate = 0;
496 uint8_t playBytesPerSample = 0;
497 uint8_t playChannels = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 {
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000499 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000500
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000501 // Store copies under lock and use copies hereafter to avoid race with
502 // setter methods.
503 playSampleRate = _playSampleRate;
504 playBytesPerSample = _playBytesPerSample;
505 playChannels = _playChannels;
506
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 // Ensure that user has initialized all essential members
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000508 if ((playBytesPerSample == 0) ||
509 (playChannels == 0) ||
510 (playSampleRate == 0))
niklase@google.com470e71d2011-07-07 08:21:25 +0000511 {
512 assert(false);
513 return -1;
514 }
515
516 _playSamples = nSamples;
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000517 _playSize = playBytesPerSample * nSamples; // {2,4}*nSamples
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000518 if (_playSize > kMaxBufferSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000519 {
520 assert(false);
521 return -1;
522 }
523
524 if (nSamples != _playSamples)
525 {
526 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "invalid number of samples to be played out (%d)", nSamples);
527 return -1;
528 }
529 }
530
pbos@webrtc.org25509882013-04-09 10:30:35 +0000531 uint32_t nSamplesOut(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000532
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000533 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +0000534
535 if (_ptrCbAudioTransport == NULL)
536 {
537 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to feed data to playout (AudioTransport does not exist)");
538 return 0;
539 }
540
541 if (_ptrCbAudioTransport)
542 {
pbos@webrtc.org25509882013-04-09 10:30:35 +0000543 uint32_t res(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000544
545 res = _ptrCbAudioTransport->NeedMorePlayData(_playSamples,
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000546 playBytesPerSample,
547 playChannels,
548 playSampleRate,
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 &_playBuffer[0],
550 nSamplesOut);
551 if (res != 0)
552 {
553 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "NeedMorePlayData() failed");
554 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 }
556
557 return nSamplesOut;
558}
559
560// ----------------------------------------------------------------------------
561// GetPlayoutData
562// ----------------------------------------------------------------------------
563
pbos@webrtc.org25509882013-04-09 10:30:35 +0000564int32_t AudioDeviceBuffer::GetPlayoutData(void* audioBuffer)
niklase@google.com470e71d2011-07-07 08:21:25 +0000565{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000566 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000567
punyabrata@webrtc.orgc9801462011-11-29 18:49:54 +0000568 if (_playSize > kMaxBufferSizeBytes)
569 {
570 WEBRTC_TRACE(kTraceError, kTraceUtility, _id, "_playSize %i exceeds "
571 "kMaxBufferSizeBytes in AudioDeviceBuffer::GetPlayoutData", _playSize);
572 assert(false);
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000573 return -1;
574 }
punyabrata@webrtc.orgc9801462011-11-29 18:49:54 +0000575
niklase@google.com470e71d2011-07-07 08:21:25 +0000576 memcpy(audioBuffer, &_playBuffer[0], _playSize);
577
578 if (_playFile.Open())
579 {
580 // write to binary file in mono or stereo (interleaved)
581 _playFile.Write(&_playBuffer[0], _playSize);
582 }
583
584 return _playSamples;
585}
586
niklase@google.com470e71d2011-07-07 08:21:25 +0000587} // namespace webrtc