blob: 12c41a811f2db35fb99a2029614d831a1d357df9 [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),
niklase@google.com470e71d2011-07-07 08:21:25 +000049 _playDelayMS(0),
50 _recDelayMS(0),
xians@webrtc.org233c58d2013-05-06 11:52:47 +000051 _clockDrift(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000052 // valid ID will be set later by SetId, use -1 for now
53 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s created", __FUNCTION__);
xians@webrtc.orgeff3c892011-12-06 10:02:56 +000054 memset(_recBuffer, 0, kMaxBufferSizeBytes);
55 memset(_playBuffer, 0, kMaxBufferSizeBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +000056}
57
58// ----------------------------------------------------------------------------
59// dtor
60// ----------------------------------------------------------------------------
61
62AudioDeviceBuffer::~AudioDeviceBuffer()
63{
64 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__);
65 {
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +000066 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000067
68 _recFile.Flush();
69 _recFile.CloseFile();
70 delete &_recFile;
71
72 _playFile.Flush();
73 _playFile.CloseFile();
74 delete &_playFile;
niklase@google.com470e71d2011-07-07 08:21:25 +000075 }
76
77 delete &_critSect;
78 delete &_critSectCb;
79}
80
81// ----------------------------------------------------------------------------
82// SetId
83// ----------------------------------------------------------------------------
84
pbos@webrtc.org25509882013-04-09 10:30:35 +000085void AudioDeviceBuffer::SetId(uint32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000086{
87 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "AudioDeviceBuffer::SetId(id=%d)", id);
88 _id = id;
89}
90
91// ----------------------------------------------------------------------------
92// RegisterAudioCallback
93// ----------------------------------------------------------------------------
94
pbos@webrtc.org25509882013-04-09 10:30:35 +000095int32_t AudioDeviceBuffer::RegisterAudioCallback(AudioTransport* audioCallback)
niklase@google.com470e71d2011-07-07 08:21:25 +000096{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +000097 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +000098 _ptrCbAudioTransport = audioCallback;
99
100 return 0;
101}
102
103// ----------------------------------------------------------------------------
104// InitPlayout
105// ----------------------------------------------------------------------------
106
pbos@webrtc.org25509882013-04-09 10:30:35 +0000107int32_t AudioDeviceBuffer::InitPlayout()
niklase@google.com470e71d2011-07-07 08:21:25 +0000108{
109 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 return 0;
111}
112
113// ----------------------------------------------------------------------------
114// InitRecording
115// ----------------------------------------------------------------------------
116
pbos@webrtc.org25509882013-04-09 10:30:35 +0000117int32_t AudioDeviceBuffer::InitRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000118{
119 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 return 0;
121}
122
123// ----------------------------------------------------------------------------
124// SetRecordingSampleRate
125// ----------------------------------------------------------------------------
126
pbos@webrtc.org25509882013-04-09 10:30:35 +0000127int32_t AudioDeviceBuffer::SetRecordingSampleRate(uint32_t fsHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000128{
129 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetRecordingSampleRate(fsHz=%u)", fsHz);
130
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000131 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000132 _recSampleRate = fsHz;
133 return 0;
134}
135
136// ----------------------------------------------------------------------------
137// SetPlayoutSampleRate
138// ----------------------------------------------------------------------------
139
pbos@webrtc.org25509882013-04-09 10:30:35 +0000140int32_t AudioDeviceBuffer::SetPlayoutSampleRate(uint32_t fsHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000141{
142 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetPlayoutSampleRate(fsHz=%u)", fsHz);
143
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000144 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 _playSampleRate = fsHz;
146 return 0;
147}
148
149// ----------------------------------------------------------------------------
150// RecordingSampleRate
151// ----------------------------------------------------------------------------
152
pbos@webrtc.org25509882013-04-09 10:30:35 +0000153int32_t AudioDeviceBuffer::RecordingSampleRate() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000154{
155 return _recSampleRate;
156}
157
158// ----------------------------------------------------------------------------
159// PlayoutSampleRate
160// ----------------------------------------------------------------------------
161
pbos@webrtc.org25509882013-04-09 10:30:35 +0000162int32_t AudioDeviceBuffer::PlayoutSampleRate() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000163{
164 return _playSampleRate;
165}
166
167// ----------------------------------------------------------------------------
168// SetRecordingChannels
169// ----------------------------------------------------------------------------
170
pbos@webrtc.org25509882013-04-09 10:30:35 +0000171int32_t AudioDeviceBuffer::SetRecordingChannels(uint8_t channels)
niklase@google.com470e71d2011-07-07 08:21:25 +0000172{
173 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetRecordingChannels(channels=%u)", channels);
174
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000175 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000176 _recChannels = channels;
177 _recBytesPerSample = 2*channels; // 16 bits per sample in mono, 32 bits in stereo
178 return 0;
179}
180
181// ----------------------------------------------------------------------------
182// SetPlayoutChannels
183// ----------------------------------------------------------------------------
184
pbos@webrtc.org25509882013-04-09 10:30:35 +0000185int32_t AudioDeviceBuffer::SetPlayoutChannels(uint8_t channels)
niklase@google.com470e71d2011-07-07 08:21:25 +0000186{
187 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "AudioDeviceBuffer::SetPlayoutChannels(channels=%u)", channels);
188
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000189 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 _playChannels = channels;
191 // 16 bits per sample in mono, 32 bits in stereo
192 _playBytesPerSample = 2*channels;
193 return 0;
194}
195
196// ----------------------------------------------------------------------------
197// SetRecordingChannel
198//
199// Select which channel to use while recording.
200// This API requires that stereo is enabled.
201//
202// Note that, the nChannel parameter in RecordedDataIsAvailable will be
203// set to 2 even for kChannelLeft and kChannelRight. However, nBytesPerSample
204// will be 2 instead of 4 four these cases.
205// ----------------------------------------------------------------------------
206
pbos@webrtc.org25509882013-04-09 10:30:35 +0000207int32_t AudioDeviceBuffer::SetRecordingChannel(const AudioDeviceModule::ChannelType channel)
niklase@google.com470e71d2011-07-07 08:21:25 +0000208{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000209 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000210
211 if (_recChannels == 1)
212 {
213 return -1;
214 }
215
216 if (channel == AudioDeviceModule::kChannelBoth)
217 {
218 // two bytes per channel
219 _recBytesPerSample = 4;
220 }
221 else
222 {
223 // only utilize one out of two possible channels (left or right)
224 _recBytesPerSample = 2;
225 }
226 _recChannel = channel;
227
228 return 0;
229}
230
231// ----------------------------------------------------------------------------
232// RecordingChannel
233// ----------------------------------------------------------------------------
234
pbos@webrtc.org25509882013-04-09 10:30:35 +0000235int32_t AudioDeviceBuffer::RecordingChannel(AudioDeviceModule::ChannelType& channel) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000236{
237 channel = _recChannel;
238 return 0;
239}
240
241// ----------------------------------------------------------------------------
242// RecordingChannels
243// ----------------------------------------------------------------------------
244
pbos@webrtc.org25509882013-04-09 10:30:35 +0000245uint8_t AudioDeviceBuffer::RecordingChannels() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000246{
247 return _recChannels;
248}
249
250// ----------------------------------------------------------------------------
251// PlayoutChannels
252// ----------------------------------------------------------------------------
253
pbos@webrtc.org25509882013-04-09 10:30:35 +0000254uint8_t AudioDeviceBuffer::PlayoutChannels() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000255{
256 return _playChannels;
257}
258
259// ----------------------------------------------------------------------------
260// SetCurrentMicLevel
261// ----------------------------------------------------------------------------
262
pbos@webrtc.org25509882013-04-09 10:30:35 +0000263int32_t AudioDeviceBuffer::SetCurrentMicLevel(uint32_t level)
niklase@google.com470e71d2011-07-07 08:21:25 +0000264{
265 _currentMicLevel = level;
266 return 0;
267}
268
269// ----------------------------------------------------------------------------
270// NewMicLevel
271// ----------------------------------------------------------------------------
272
pbos@webrtc.org25509882013-04-09 10:30:35 +0000273uint32_t AudioDeviceBuffer::NewMicLevel() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000274{
275 return _newMicLevel;
276}
277
278// ----------------------------------------------------------------------------
279// SetVQEData
280// ----------------------------------------------------------------------------
281
pbos@webrtc.org25509882013-04-09 10:30:35 +0000282int32_t AudioDeviceBuffer::SetVQEData(uint32_t playDelayMS, uint32_t recDelayMS, int32_t clockDrift)
niklase@google.com470e71d2011-07-07 08:21:25 +0000283{
284 if ((playDelayMS + recDelayMS) > 300)
285 {
286 WEBRTC_TRACE(kTraceWarning, kTraceUtility, _id, "too long delay (play:%i rec:%i)", playDelayMS, recDelayMS, clockDrift);
287 }
288
289 _playDelayMS = playDelayMS;
290 _recDelayMS = recDelayMS;
291 _clockDrift = clockDrift;
292
293 return 0;
294}
295
296// ----------------------------------------------------------------------------
297// StartInputFileRecording
298// ----------------------------------------------------------------------------
299
pbos@webrtc.org25509882013-04-09 10:30:35 +0000300int32_t AudioDeviceBuffer::StartInputFileRecording(
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000301 const char fileName[kAdmMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000302{
303 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
304
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000305 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000306
307 _recFile.Flush();
308 _recFile.CloseFile();
309
310 return (_recFile.OpenFile(fileName, false, false, false));
311}
312
313// ----------------------------------------------------------------------------
314// StopInputFileRecording
315// ----------------------------------------------------------------------------
316
pbos@webrtc.org25509882013-04-09 10:30:35 +0000317int32_t AudioDeviceBuffer::StopInputFileRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000318{
319 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
320
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000321 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322
323 _recFile.Flush();
324 _recFile.CloseFile();
325
326 return 0;
327}
328
329// ----------------------------------------------------------------------------
330// StartOutputFileRecording
331// ----------------------------------------------------------------------------
332
pbos@webrtc.org25509882013-04-09 10:30:35 +0000333int32_t AudioDeviceBuffer::StartOutputFileRecording(
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000334 const char fileName[kAdmMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000335{
336 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
337
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000338 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000339
340 _playFile.Flush();
341 _playFile.CloseFile();
342
343 return (_playFile.OpenFile(fileName, false, false, false));
344}
345
346// ----------------------------------------------------------------------------
347// StopOutputFileRecording
348// ----------------------------------------------------------------------------
349
pbos@webrtc.org25509882013-04-09 10:30:35 +0000350int32_t AudioDeviceBuffer::StopOutputFileRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000351{
352 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
353
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000354 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000355
356 _playFile.Flush();
357 _playFile.CloseFile();
358
359 return 0;
360}
361
362// ----------------------------------------------------------------------------
363// SetRecordedBuffer
364//
365// Store recorded audio buffer in local memory ready for the actual
366// "delivery" using a callback.
367//
368// This method can also parse out left or right channel from a stereo
369// input signal, i.e., emulate mono.
370//
371// Examples:
372//
373// 16-bit,48kHz mono, 10ms => nSamples=480 => _recSize=2*480=960 bytes
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000374// 16-bit,48kHz stereo,10ms => nSamples=480 => _recSize=4*480=1920 bytes
niklase@google.com470e71d2011-07-07 08:21:25 +0000375// ----------------------------------------------------------------------------
376
pbos@webrtc.org25509882013-04-09 10:30:35 +0000377int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audioBuffer,
378 uint32_t nSamples)
niklase@google.com470e71d2011-07-07 08:21:25 +0000379{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000380 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000381
382 if (_recBytesPerSample == 0)
383 {
384 assert(false);
385 return -1;
386 }
387
388 _recSamples = nSamples;
389 _recSize = _recBytesPerSample*nSamples; // {2,4}*nSamples
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000390 if (_recSize > kMaxBufferSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 {
392 assert(false);
393 return -1;
394 }
395
396 if (nSamples != _recSamples)
397 {
398 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "invalid number of recorded samples (%d)", nSamples);
399 return -1;
400 }
401
402 if (_recChannel == AudioDeviceModule::kChannelBoth)
403 {
404 // (default) copy the complete input buffer to the local buffer
405 memcpy(&_recBuffer[0], audioBuffer, _recSize);
406 }
407 else
408 {
pbos@webrtc.org25509882013-04-09 10:30:35 +0000409 int16_t* ptr16In = (int16_t*)audioBuffer;
410 int16_t* ptr16Out = (int16_t*)&_recBuffer[0];
niklase@google.com470e71d2011-07-07 08:21:25 +0000411
412 if (AudioDeviceModule::kChannelRight == _recChannel)
413 {
414 ptr16In++;
415 }
416
417 // exctract left or right channel from input buffer to the local buffer
pbos@webrtc.org25509882013-04-09 10:30:35 +0000418 for (uint32_t i = 0; i < _recSamples; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000419 {
420 *ptr16Out = *ptr16In;
421 ptr16Out++;
422 ptr16In++;
423 ptr16In++;
424 }
425 }
426
427 if (_recFile.Open())
428 {
429 // write to binary file in mono or stereo (interleaved)
430 _recFile.Write(&_recBuffer[0], _recSize);
431 }
432
433 return 0;
434}
435
436// ----------------------------------------------------------------------------
437// DeliverRecordedData
438// ----------------------------------------------------------------------------
439
pbos@webrtc.org25509882013-04-09 10:30:35 +0000440int32_t AudioDeviceBuffer::DeliverRecordedData()
niklase@google.com470e71d2011-07-07 08:21:25 +0000441{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000442 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443
444 // Ensure that user has initialized all essential members
445 if ((_recSampleRate == 0) ||
446 (_recSamples == 0) ||
447 (_recBytesPerSample == 0) ||
448 (_recChannels == 0))
449 {
450 assert(false);
451 return -1;
452 }
453
454 if (_ptrCbAudioTransport == NULL)
455 {
456 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to deliver recorded data (AudioTransport does not exist)");
457 return 0;
458 }
459
pbos@webrtc.org25509882013-04-09 10:30:35 +0000460 int32_t res(0);
461 uint32_t newMicLevel(0);
462 uint32_t totalDelayMS = _playDelayMS +_recDelayMS;
niklase@google.com470e71d2011-07-07 08:21:25 +0000463
niklase@google.com470e71d2011-07-07 08:21:25 +0000464 res = _ptrCbAudioTransport->RecordedDataIsAvailable(&_recBuffer[0],
465 _recSamples,
466 _recBytesPerSample,
467 _recChannels,
468 _recSampleRate,
469 totalDelayMS,
470 _clockDrift,
471 _currentMicLevel,
472 newMicLevel);
473 if (res != -1)
474 {
475 _newMicLevel = newMicLevel;
476 }
477
478 return 0;
479}
480
481// ----------------------------------------------------------------------------
482// RequestPlayoutData
483// ----------------------------------------------------------------------------
484
pbos@webrtc.org25509882013-04-09 10:30:35 +0000485int32_t AudioDeviceBuffer::RequestPlayoutData(uint32_t nSamples)
niklase@google.com470e71d2011-07-07 08:21:25 +0000486{
pbos@webrtc.org25509882013-04-09 10:30:35 +0000487 uint32_t playSampleRate = 0;
488 uint8_t playBytesPerSample = 0;
489 uint8_t playChannels = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000490 {
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000491 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000492
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000493 // Store copies under lock and use copies hereafter to avoid race with
494 // setter methods.
495 playSampleRate = _playSampleRate;
496 playBytesPerSample = _playBytesPerSample;
497 playChannels = _playChannels;
498
niklase@google.com470e71d2011-07-07 08:21:25 +0000499 // Ensure that user has initialized all essential members
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000500 if ((playBytesPerSample == 0) ||
501 (playChannels == 0) ||
502 (playSampleRate == 0))
niklase@google.com470e71d2011-07-07 08:21:25 +0000503 {
504 assert(false);
505 return -1;
506 }
507
508 _playSamples = nSamples;
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000509 _playSize = playBytesPerSample * nSamples; // {2,4}*nSamples
braveyao@webrtc.org0a185222011-11-25 02:45:39 +0000510 if (_playSize > kMaxBufferSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000511 {
512 assert(false);
513 return -1;
514 }
515
516 if (nSamples != _playSamples)
517 {
518 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "invalid number of samples to be played out (%d)", nSamples);
519 return -1;
520 }
521 }
522
pbos@webrtc.org25509882013-04-09 10:30:35 +0000523 uint32_t nSamplesOut(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000524
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000525 CriticalSectionScoped lock(&_critSectCb);
niklase@google.com470e71d2011-07-07 08:21:25 +0000526
527 if (_ptrCbAudioTransport == NULL)
528 {
529 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to feed data to playout (AudioTransport does not exist)");
530 return 0;
531 }
532
533 if (_ptrCbAudioTransport)
534 {
pbos@webrtc.org25509882013-04-09 10:30:35 +0000535 uint32_t res(0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000536
537 res = _ptrCbAudioTransport->NeedMorePlayData(_playSamples,
henrika@webrtc.org19da7192013-04-05 14:34:57 +0000538 playBytesPerSample,
539 playChannels,
540 playSampleRate,
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 &_playBuffer[0],
542 nSamplesOut);
543 if (res != 0)
544 {
545 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "NeedMorePlayData() failed");
546 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 }
548
549 return nSamplesOut;
550}
551
552// ----------------------------------------------------------------------------
553// GetPlayoutData
554// ----------------------------------------------------------------------------
555
pbos@webrtc.org25509882013-04-09 10:30:35 +0000556int32_t AudioDeviceBuffer::GetPlayoutData(void* audioBuffer)
niklase@google.com470e71d2011-07-07 08:21:25 +0000557{
mflodman@webrtc.orga014ecc2012-04-12 12:15:51 +0000558 CriticalSectionScoped lock(&_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000559
punyabrata@webrtc.orgc9801462011-11-29 18:49:54 +0000560 if (_playSize > kMaxBufferSizeBytes)
561 {
562 WEBRTC_TRACE(kTraceError, kTraceUtility, _id, "_playSize %i exceeds "
563 "kMaxBufferSizeBytes in AudioDeviceBuffer::GetPlayoutData", _playSize);
564 assert(false);
leozwang@webrtc.org28f39132012-03-01 18:01:48 +0000565 return -1;
566 }
punyabrata@webrtc.orgc9801462011-11-29 18:49:54 +0000567
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 memcpy(audioBuffer, &_playBuffer[0], _playSize);
569
570 if (_playFile.Open())
571 {
572 // write to binary file in mono or stereo (interleaved)
573 _playFile.Write(&_playBuffer[0], _playSize);
574 }
575
576 return _playSamples;
577}
578
niklase@google.com470e71d2011-07-07 08:21:25 +0000579} // namespace webrtc