blob: 919c17dc338f739b8983926893e1c1b01a71f49a [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/audio/simple_sources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::Field;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::NotNull;
using ::testing::Return;
namespace media {
class MockAudioSource : public AudioOutputStream::AudioSourceCallback {
public:
MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
AudioBuffersState buffers_state));
MOCK_METHOD3(OnMoreIOData, int(AudioBus* source,
AudioBus* dest,
AudioBuffersState buffers_state));
MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
};
// ===========================================================================
// Validation of AudioParameters::AUDIO_PCM_LINEAR
//
// Test that can it be created and closed.
TEST(MacAudioTest, PCMWaveStreamGetAndClose) {
scoped_ptr<AudioManager> audio_man(AudioManager::Create());
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
8000, 16, 1024));
ASSERT_TRUE(NULL != oas);
oas->Close();
}
// Test that it can be opened and closed.
TEST(MacAudioTest, PCMWaveStreamOpenAndClose) {
scoped_ptr<AudioManager> audio_man(AudioManager::Create());
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
8000, 16, 1024));
ASSERT_TRUE(NULL != oas);
EXPECT_TRUE(oas->Open());
oas->Close();
}
// This test produces actual audio for 1.5 seconds on the default wave device at
// 44.1K s/sec. Parameters have been chosen carefully so you should not hear
// pops or noises while the sound is playing. The sound must also be identical
// to the sound of PCMWaveStreamPlay200HzTone22KssMono test.
TEST(MacAudioTest, PCMWaveStreamPlay200HzTone44KssMono) {
scoped_ptr<AudioManager> audio_man(AudioManager::Create());
if (!audio_man->HasAudioOutputDevices())
return;
uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
AudioParameters::kAudioCDSampleRate, 16, frames_100_ms));
ASSERT_TRUE(NULL != oas);
EXPECT_TRUE(oas->Open());
SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate);
oas->SetVolume(0.5);
oas->Start(&source);
usleep(500000);
// Test that the volume is within the set limits.
double volume = 0.0;
oas->GetVolume(&volume);
EXPECT_LT(volume, 0.51);
EXPECT_GT(volume, 0.49);
oas->Stop();
oas->Close();
}
// This test produces actual audio for 1.5 seconds on the default wave device at
// 22K s/sec. Parameters have been chosen carefully so you should not hear pops
// or noises while the sound is playing. The sound must also be identical to the
// sound of PCMWaveStreamPlay200HzTone44KssMono test.
TEST(MacAudioTest, PCMWaveStreamPlay200HzTone22KssMono) {
scoped_ptr<AudioManager> audio_man(AudioManager::Create());
if (!audio_man->HasAudioOutputDevices())
return;
uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
AudioParameters::kAudioCDSampleRate / 2, 16,
frames_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate/2);
EXPECT_TRUE(oas->Open());
oas->Start(&source);
usleep(1500000);
oas->Stop();
oas->Close();
}
// Custom action to clear a memory buffer.
static int ClearBuffer(AudioBus* audio_bus,
AudioBuffersState buffers_state) {
audio_bus->Zero();
return audio_bus->frames();
}
TEST(MacAudioTest, PCMWaveStreamPendingBytes) {
scoped_ptr<AudioManager> audio_man(AudioManager::Create());
if (!audio_man->HasAudioOutputDevices())
return;
uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
AudioParameters::kAudioCDSampleRate, 16, frames_100_ms));
ASSERT_TRUE(NULL != oas);
NiceMock<MockAudioSource> source;
EXPECT_TRUE(oas->Open());
uint32 bytes_100_ms = frames_100_ms * 2;
// We expect the amount of pending bytes will reaching |bytes_100_ms|
// because the audio output stream has a double buffer scheme.
// And then we will try to provide zero data so the amount of pending bytes
// will go down and eventually read zero.
InSequence s;
EXPECT_CALL(source, OnMoreData(NotNull(),
Field(&AudioBuffersState::pending_bytes, 0)))
.WillOnce(Invoke(ClearBuffer));
EXPECT_CALL(source, OnMoreData(NotNull(),
Field(&AudioBuffersState::pending_bytes,
bytes_100_ms)))
.WillOnce(Invoke(ClearBuffer));
EXPECT_CALL(source, OnMoreData(NotNull(),
Field(&AudioBuffersState::pending_bytes,
bytes_100_ms)))
.WillOnce(Return(0));
EXPECT_CALL(source, OnMoreData(NotNull(), _))
.Times(AnyNumber())
.WillRepeatedly(Return(0));
oas->Start(&source);
usleep(500000);
oas->Stop();
oas->Close();
}
} // namespace media