summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-29 09:02:06 +0000
committerhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-29 09:02:06 +0000
commitd5408eb65eb4a9d12c67f608a1162d31a11c63b2 (patch)
tree37f3e12aeabbdc7256cd75e415fa2bdd37589928 /media
parent59404dd4e61e8d92aaf05a7c2457100eb4897b46 (diff)
downloadchromium_src-d5408eb65eb4a9d12c67f608a1162d31a11c63b2.zip
chromium_src-d5408eb65eb4a9d12c67f608a1162d31a11c63b2.tar.gz
chromium_src-d5408eb65eb4a9d12c67f608a1162d31a11c63b2.tar.bz2
Revert 111890 - This patch ensures that the audio_output_win_unittest works for AUDIO_PCM_LOW_LATENCY.
It seems like only test which utilized AUDIO_PCM_LOW_LATENCY has been broken for a while. It was most likely I who broke it when I added support for WASAPI output. Anyhow, in this patch, I ensure that we can still test using the low-larency flag. A buffer size of 10ms is used on Vista and higher (<=> WASAPI) and 50ms is used (as before) in XP. I have also modified the sinus source since it contained two issues actually. 1) It did not store a valid state between each frame (=> distorsion at end-points). 2) The volume 2^15 was too high and could lead to odd effects for negative numbers. Both these things are fixed in this CL and all tones now sounds better. The old tones were all distorted. BUG=none TEST=audio_output_win_unittest Review URL: http://codereview.chromium.org/8678012 TBR=henrika@chromium.org Review URL: http://codereview.chromium.org/8725027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111892 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/simple_sources.cc18
-rw-r--r--media/audio/simple_sources.h1
-rw-r--r--media/audio/win/audio_output_win_unittest.cc59
3 files changed, 28 insertions, 50 deletions
diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc
index 4cd0ba3..4078315 100644
--- a/media/audio/simple_sources.cc
+++ b/media/audio/simple_sources.cc
@@ -21,8 +21,7 @@ SineWaveAudioSource::SineWaveAudioSource(Format format, int channels,
: format_(format),
channels_(channels),
freq_(freq),
- sample_freq_(sample_freq),
- time_state_(0) {
+ sample_freq_(sample_freq) {
// TODO(cpu): support other formats.
DCHECK((format_ == FORMAT_16BIT_LINEAR_PCM) && (channels_ == 1));
}
@@ -32,19 +31,14 @@ SineWaveAudioSource::SineWaveAudioSource(Format format, int channels,
uint32 SineWaveAudioSource::OnMoreData(
AudioOutputStream* stream, uint8* dest, uint32 max_size,
AudioBuffersState audio_buffers) {
- const double kTwoPi = 2.0 * 3.141592653589793;
+ const double kTwoPi = 2.0 * 3.141592653589;
double f = freq_ / sample_freq_;
int16* sin_tbl = reinterpret_cast<int16*>(dest);
uint32 len = max_size / sizeof(int16);
-
- // The table is filled with s(t) = kint16max*sin(Theta*t),
- // where Theta = 2*PI*fs.
- // We store the discrete time value |t| in a member to ensure that the
- // next pass starts at a correct state.
- for (uint32 n = 0; n < len; ++n) {
- double theta = kTwoPi * f;
- sin_tbl[n] = static_cast<int16>(kint16max * sin(theta * time_state_));
- ++time_state_;
+ // The table is filled with s(t) = 32768*sin(2PI*f*t).
+ for (uint32 ix = 0; ix != len; ++ix) {
+ double th = kTwoPi * ix * f;
+ sin_tbl[ix] = static_cast<int16>((1 << 15) * sin(th));
}
return max_size;
}
diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h
index a4373a0..dd2782c 100644
--- a/media/audio/simple_sources.h
+++ b/media/audio/simple_sources.h
@@ -36,7 +36,6 @@ class MEDIA_EXPORT SineWaveAudioSource
int channels_;
double freq_;
double sample_freq_;
- int time_state_;
};
// Defines an interface for pushing audio output. In contrast, the interfaces
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index d2447c5..4fcc5c8 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -10,11 +10,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/sync_socket.h"
-#include "base/win/scoped_com_initializer.h"
-#include "base/win/windows_version.h"
-#include "media/base/limits.h"
#include "media/audio/audio_io.h"
-#include "media/audio/audio_util.h"
#include "media/audio/audio_manager.h"
#include "media/audio/simple_sources.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -29,8 +25,6 @@ using ::testing::NiceMock;
using ::testing::NotNull;
using ::testing::Return;
-using base::win::ScopedCOMInitializer;
-
static const wchar_t kAudioFile1_16b_m_16K[]
= L"media\\test\\data\\sweep02_16b_mono_16KHz.raw";
@@ -237,7 +231,7 @@ TEST(WinAudioTest, PCMWaveStreamGetAndClose) {
oas->Close();
}
-// Test that can it be cannot be created with invalid parameters.
+// Test that can it be cannot be created with crazy parameters
TEST(WinAudioTest, SanityOnMakeParams) {
if (IsRunningHeadless())
return;
@@ -261,8 +255,7 @@ TEST(WinAudioTest, SanityOnMakeParams) {
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, 0)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16,
- media::Limits::kMaxSamplesPerPacket + 1)));
+ AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, 100000)));
}
// Test that it can be opened and closed.
@@ -540,10 +533,11 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
oas->Close();
}
-// With the low latency mode, WASAPI is utilized by default for Vista and
-// higher and Wave is used for XP and lower. It is possible to utilize a
-// smaller buffer size for WASAPI than for Wave.
-TEST(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) {
+// With the low latency mode, we have two buffers instead of 3 and we
+// should be able to handle 20ms buffers at 44KHz. See also the SyncSocketBasic
+// test below.
+// TODO(cpu): right now the best we can do is 50ms before it sounds choppy.
+TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44KssLowLatency) {
if (IsRunningHeadless())
return;
AudioManager* audio_man = AudioManager::GetAudioManager();
@@ -551,23 +545,15 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) {
if (!audio_man->HasAudioOutputDevices())
return;
- // The WASAPI API requires a correct COM environment.
- ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
-
- // Use 10 ms buffer size for WASAPI and 50 ms buffer size for Wave.
- // Take the existing native sample rate into account.
- int sample_rate = static_cast<int>(media::GetAudioHardwareSampleRate());
- uint32 samples_10_ms = sample_rate / 100;
- int n = 1;
- (base::win::GetVersion() <= base::win::VERSION_XP) ? n = 5 : n = 1;
+ uint32 samples_50_ms = AudioParameters::kAudioCDSampleRate / 20;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
- CHANNEL_LAYOUT_MONO, sample_rate,
- 16, n * samples_10_ms));
+ CHANNEL_LAYOUT_MONO, AudioParameters::kAudioCDSampleRate,
+ 16, samples_50_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
- 200.0, sample_rate);
+ 200.0, AudioParameters::kAudioCDSampleRate);
EXPECT_TRUE(oas->Open());
oas->SetVolume(1.0);
@@ -665,7 +651,7 @@ struct SyncThreadContext {
base::SyncSocket* socket;
int sample_rate;
double sine_freq;
- uint32 packet_size_bytes;
+ uint32 packet_size;
};
// This thread provides the data that the SyncSocketSource above needs
@@ -686,11 +672,11 @@ DWORD __stdcall SyncSocketThread(void* context) {
AudioBuffersState buffers_state;
int times = 0;
- for (int ix = 0; ix < kTwoSecBytes; ix += ctx.packet_size_bytes) {
+ for (int ix = 0; ix < kTwoSecBytes; ix += ctx.packet_size) {
if (ctx.socket->Receive(&buffers_state, sizeof(buffers_state)) == 0)
break;
if ((times > 0) && (buffers_state.pending_bytes < 1000)) __debugbreak();
- ctx.socket->Send(&buffer[ix], ctx.packet_size_bytes);
+ ctx.socket->Send(&buffer[ix], ctx.packet_size);
++times;
}
@@ -699,13 +685,11 @@ DWORD __stdcall SyncSocketThread(void* context) {
}
// Test the basic operation of AudioOutputStream used with a SyncSocket.
-// The emphasis is to verify that it is possible to feed data to the audio
-// layer using a source based on SyncSocket. In a real situation we would
-// go for the low-latency version in combination with SyncSocket, but to keep
-// the test more simple, AUDIO_PCM_LINEAR is utilized instead. The main
-// principle of the test still remains and we avoid the additional complexity
-// related to the two different audio-layers for AUDIO_PCM_LOW_LATENCY.
-// In this test you should hear a continuous 200Hz tone for 2 seconds.
+// The emphasis is to test low-latency with buffers less than 100ms. With
+// the waveout api it seems not possible to go below 50ms. In this test
+// you should hear a continous 200Hz tone.
+//
+// TODO(cpu): This actually sounds choppy most of the time. Fix it.
TEST(WinAudioTest, SyncSocketBasic) {
if (IsRunningHeadless())
return;
@@ -718,10 +702,11 @@ TEST(WinAudioTest, SyncSocketBasic) {
int sample_rate = AudioParameters::kAudioCDSampleRate;
const uint32 kSamples20ms = sample_rate / 50;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+ AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
CHANNEL_LAYOUT_MONO, sample_rate, 16, kSamples20ms));
ASSERT_TRUE(NULL != oas);
+ // compute buffer size for 20ms of audio, 882 samples (mono).
ASSERT_TRUE(oas->Open());
base::SyncSocket* sockets[2];
@@ -732,7 +717,7 @@ TEST(WinAudioTest, SyncSocketBasic) {
SyncThreadContext thread_context;
thread_context.sample_rate = sample_rate;
thread_context.sine_freq = 200.0;
- thread_context.packet_size_bytes = kSamples20ms * 2;
+ thread_context.packet_size = kSamples20ms;
thread_context.socket = sockets[1];
HANDLE thread = ::CreateThread(NULL, 0, SyncSocketThread,