| // Copyright 2016 Google Inc. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "starboard/audio_sink.h" | |
| #include <vector> | |
| #include "starboard/nplb/audio_sink_helpers.h" | |
| #include "testing/gtest/include/gtest/gtest.h" | |
| namespace starboard { | |
| namespace nplb { | |
| namespace { | |
| void UpdateSourceStatusFuncStub(int* frames_in_buffer, | |
| int* offset_in_frames, | |
| bool* is_playing, | |
| bool* is_eos_reached, | |
| void* context) {} | |
| void ConsumeFramesFuncStub(int frames_consumed, void* context) {} | |
| } // namespace | |
| TEST(SbAudioSinkCreateTest, SunnyDay) { | |
| ASSERT_GE(SbAudioSinkGetMaxChannels(), 1); | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels()); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, | |
| reinterpret_cast<void*>(1)); | |
| EXPECT_TRUE(SbAudioSinkIsValid(audio_sink)); | |
| SbAudioSinkDestroy(audio_sink); | |
| } | |
| TEST(SbAudioSinkCreateTest, SunnyDayAllCombinations) { | |
| std::vector<SbMediaAudioSampleType> sample_types; | |
| if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeInt16)) { | |
| sample_types.push_back(kSbMediaAudioSampleTypeInt16); | |
| } | |
| if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeFloat32)) { | |
| sample_types.push_back(kSbMediaAudioSampleTypeFloat32); | |
| } | |
| std::vector<SbMediaAudioFrameStorageType> storage_types; | |
| if (SbAudioSinkIsAudioFrameStorageTypeSupported( | |
| kSbMediaAudioFrameStorageTypeInterleaved)) { | |
| storage_types.push_back(kSbMediaAudioFrameStorageTypeInterleaved); | |
| } | |
| if (SbAudioSinkIsAudioFrameStorageTypeSupported( | |
| kSbMediaAudioFrameStorageTypePlanar)) { | |
| storage_types.push_back(kSbMediaAudioFrameStorageTypePlanar); | |
| } | |
| for (size_t sample_type = 0; sample_type < sample_types.size(); | |
| ++sample_type) { | |
| for (size_t storage_type = 0; storage_type < storage_types.size(); | |
| ++storage_type) { | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels(), | |
| sample_types[sample_type], | |
| storage_types[storage_type]); | |
| // It should at least support stereo and the claimed max channels. | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_TRUE(SbAudioSinkIsValid(audio_sink)); | |
| SbAudioSinkDestroy(audio_sink); | |
| if (SbAudioSinkGetMaxChannels() > 2) { | |
| AudioSinkTestFrameBuffers frame_buffers(2, sample_types[sample_type], | |
| storage_types[storage_type]); | |
| audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_TRUE(SbAudioSinkIsValid(audio_sink)); | |
| SbAudioSinkDestroy(audio_sink); | |
| } | |
| } | |
| } | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidChannels) { | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels()); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| 0, // |channels| is 0 | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidFrequency) { | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels()); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), 0, // |sampling_frequency_hz| is 0 | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| const int kOddFrequency = 12345; | |
| if (SbAudioSinkGetNearestSupportedSampleFrequency(kOddFrequency) != | |
| kOddFrequency) { | |
| audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| kOddFrequency, // |sampling_frequency_hz| is unsupported | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidSampleType) { | |
| SbMediaAudioSampleType invalid_sample_type; | |
| if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeInt16)) { | |
| if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeFloat32)) { | |
| return; | |
| } | |
| invalid_sample_type = kSbMediaAudioSampleTypeFloat32; | |
| } else { | |
| invalid_sample_type = kSbMediaAudioSampleTypeInt16; | |
| } | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels(), | |
| invalid_sample_type); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| SbAudioSinkGetMaxChannels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| invalid_sample_type, // |sample_type| is invalid | |
| frame_buffers.storage_type(), frame_buffers.frame_buffers(), | |
| frame_buffers.frames_per_channel(), UpdateSourceStatusFuncStub, | |
| ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidFrameStorageType) { | |
| SbMediaAudioFrameStorageType invalid_storage_type; | |
| if (SbAudioSinkIsAudioFrameStorageTypeSupported( | |
| kSbMediaAudioFrameStorageTypeInterleaved)) { | |
| if (SbAudioSinkIsAudioFrameStorageTypeSupported( | |
| kSbMediaAudioFrameStorageTypePlanar)) { | |
| return; | |
| } | |
| invalid_storage_type = kSbMediaAudioFrameStorageTypePlanar; | |
| } else { | |
| invalid_storage_type = kSbMediaAudioFrameStorageTypeInterleaved; | |
| } | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels(), | |
| invalid_storage_type); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| SbAudioSinkGetMaxChannels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), | |
| invalid_storage_type, // |storage_type| is invalid | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidFrameBuffers) { | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels()); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| NULL, // |frame_buffers| is NULL | |
| frame_buffers.frames_per_channel(), UpdateSourceStatusFuncStub, | |
| ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), | |
| 0, // |frames_per_channel| is 0 | |
| UpdateSourceStatusFuncStub, ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| TEST(SbAudioSinkCreateTest, RainyDayInvalidCallback) { | |
| AudioSinkTestFrameBuffers frame_buffers(SbAudioSinkGetMaxChannels()); | |
| SbAudioSink audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| NULL, // |update_source_status_func| is NULL | |
| ConsumeFramesFuncStub, NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| audio_sink = SbAudioSinkCreate( | |
| frame_buffers.channels(), | |
| SbAudioSinkGetNearestSupportedSampleFrequency(44100), | |
| frame_buffers.sample_type(), frame_buffers.storage_type(), | |
| frame_buffers.frame_buffers(), frame_buffers.frames_per_channel(), | |
| UpdateSourceStatusFuncStub, | |
| NULL, // |consume_frames_func| is NULL | |
| NULL); | |
| EXPECT_FALSE(SbAudioSinkIsValid(audio_sink)); | |
| } | |
| } // namespace nplb | |
| } // namespace starboard |