2 * Copyright (C) 2014 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "gtest/gtest.h"
23 #if defined(TARGET_DARWIN_OSX)
24 #include "cores/AudioEngine/Sinks/osx/CoreAudioHardware.h"
25 #include "cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h"
26 #include "cores/AudioEngine/Utils/AEUtil.h"
29 extern float ScoreStream(const AudioStreamBasicDescription &desc, const AEAudioFormat &format);
31 std::vector<AudioStreamBasicDescription> stereoFormatsWithPassthrough;
32 std::vector<AudioStreamBasicDescription> stereoFormatsWithoutPassthrough;
33 std::vector<AudioStreamBasicDescription> allFormatsWithPassthrough;
34 std::vector<AudioStreamBasicDescription> allFormatsWithoutPassthrough;
36 void addLPCMFormats(std::vector<AudioStreamBasicDescription> &streamFormats)
38 AudioStreamBasicDescription streamFormat;
40 FillOutASBDForLPCM(streamFormat, 96000, 8, 16, 16, false, false, false);
41 streamFormats.push_back(streamFormat); // + 0
43 FillOutASBDForLPCM(streamFormat, 48000, 8, 16, 16, false, false, false);
44 streamFormats.push_back(streamFormat); // + 1
46 FillOutASBDForLPCM(streamFormat, 44100, 8, 16, 16, false, false, false);
47 streamFormats.push_back(streamFormat); // + 2
49 FillOutASBDForLPCM(streamFormat, 96000, 8, 20, 20, false, false, false);
50 streamFormats.push_back(streamFormat); // + 3
52 FillOutASBDForLPCM(streamFormat, 48000, 8, 20, 20, false, false, false);
53 streamFormats.push_back(streamFormat); // + 4
55 FillOutASBDForLPCM(streamFormat, 44100, 8, 20, 20, false, false, false);
56 streamFormats.push_back(streamFormat); // + 5
58 FillOutASBDForLPCM(streamFormat, 96000, 8, 24, 24, false, false, false);
59 streamFormats.push_back(streamFormat); // + 6
61 FillOutASBDForLPCM(streamFormat, 48000, 8, 24, 24, false, false, false);
62 streamFormats.push_back(streamFormat); // + 7
64 FillOutASBDForLPCM(streamFormat, 44100, 8, 24, 24, false, false, false);
65 streamFormats.push_back(streamFormat); // + 8
68 void addPassthroughFormats(std::vector<AudioStreamBasicDescription> &streamFormats)
70 AudioStreamBasicDescription streamFormat;
72 FillOutASBDForLPCM(streamFormat, 96000, 2, 16, 16, false, false, false);
73 streamFormat.mFormatID = kAudioFormat60958AC3;
74 streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 0
76 FillOutASBDForLPCM(streamFormat, 48000, 2, 16, 16, false, false, false);
77 streamFormat.mFormatID = kAudioFormat60958AC3;
78 streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 1
80 FillOutASBDForLPCM(streamFormat, 44100, 2, 16, 16, false, false, false);
81 streamFormat.mFormatID = kAudioFormat60958AC3;
82 streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 2
85 void initStereoFormatsWithoutPassthrough()
87 AudioStreamBasicDescription streamFormat;
88 FillOutASBDForLPCM(streamFormat, 96000, 2, 16, 16, false, false, false);
89 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 0
91 FillOutASBDForLPCM(streamFormat, 48000, 2, 16, 16, false, false, false);
92 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 1
94 FillOutASBDForLPCM(streamFormat, 44100, 2, 16, 16, false, false, false);
95 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 2
97 FillOutASBDForLPCM(streamFormat, 96000, 2, 20, 20, false, false, false);
98 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 3
100 FillOutASBDForLPCM(streamFormat, 48000, 2, 20, 20, false, false, false);
101 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 4
103 FillOutASBDForLPCM(streamFormat, 44100, 2, 20, 20, false, false, false);
104 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 5
106 FillOutASBDForLPCM(streamFormat, 96000, 2, 24, 24, false, false, false);
107 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 6
109 FillOutASBDForLPCM(streamFormat, 48000, 2, 24, 24, false, false, false);
110 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 7
112 FillOutASBDForLPCM(streamFormat, 44100, 2, 24, 24, false, false, false);
113 stereoFormatsWithoutPassthrough.push_back(streamFormat); // 8
116 void initStreamFormats()
118 stereoFormatsWithPassthrough.clear();
119 stereoFormatsWithoutPassthrough.clear();
120 allFormatsWithPassthrough.clear();
121 allFormatsWithoutPassthrough.clear();
123 initStereoFormatsWithoutPassthrough();
125 stereoFormatsWithPassthrough = stereoFormatsWithoutPassthrough;
126 allFormatsWithoutPassthrough = stereoFormatsWithoutPassthrough;
128 addLPCMFormats( allFormatsWithoutPassthrough);
130 allFormatsWithPassthrough = allFormatsWithoutPassthrough;
132 addPassthroughFormats(stereoFormatsWithPassthrough);
133 addPassthroughFormats(allFormatsWithPassthrough);
137 AEAudioFormat getAC3AEFormat()
139 AEAudioFormat srcFormat;
140 srcFormat.m_dataFormat = AE_FMT_AC3;
141 srcFormat.m_sampleRate = 48000;
142 srcFormat.m_encodedRate = 48000;
143 srcFormat.m_channelLayout = AE_CH_LAYOUT_2_0;
144 srcFormat.m_frames = 0;
145 srcFormat.m_frameSamples = 0;
146 srcFormat.m_frameSize = 0;
150 AEAudioFormat getStereo22050AEFormat()
152 AEAudioFormat srcFormat;
153 srcFormat.m_dataFormat = AE_FMT_FLOAT;
154 srcFormat.m_sampleRate = 22050;
155 srcFormat.m_encodedRate = 0;
156 srcFormat.m_channelLayout = AE_CH_LAYOUT_2_0;
157 srcFormat.m_frames = 0;
158 srcFormat.m_frameSamples = 0;
159 srcFormat.m_frameSize = 0;
163 AEAudioFormat getStereo48000AEFormat()
165 AEAudioFormat srcFormat;
166 srcFormat.m_dataFormat = AE_FMT_FLOAT;
167 srcFormat.m_sampleRate = 48000;
168 srcFormat.m_encodedRate = 0;
169 srcFormat.m_channelLayout = AE_CH_LAYOUT_2_0;
170 srcFormat.m_frames = 0;
171 srcFormat.m_frameSamples = 0;
172 srcFormat.m_frameSize = 0;
176 AEAudioFormat getLPCM96000AEFormat()
178 AEAudioFormat srcFormat;
179 srcFormat.m_dataFormat = AE_FMT_FLOAT;
180 srcFormat.m_sampleRate = 96000;
181 srcFormat.m_encodedRate = 0;
182 srcFormat.m_channelLayout = AE_CH_LAYOUT_5_1;
183 srcFormat.m_frames = 0;
184 srcFormat.m_frameSamples = 0;
185 srcFormat.m_frameSize = 0;
189 unsigned int findMatchingFormat(const std::vector<AudioStreamBasicDescription> &formatList, const AEAudioFormat &srcFormat)
191 unsigned int formatIdx = 0;
192 float highestScore = 0;
193 float currentScore = 0;
195 // fprintf(stderr, "%s: Matching streamFormat for source: %s with samplerate: %d\n", __FUNCTION__, CAEUtil::DataFormatToStr(srcFormat.m_dataFormat), srcFormat.m_sampleRate);
196 for (unsigned int i = 0; i < formatList.size(); i++)
198 AudioStreamBasicDescription desc = formatList[i];
199 std::string formatString;
200 currentScore = ScoreStream(desc, srcFormat);
201 // fprintf(stderr, "%s: Physical Format: %s idx: %d rated %f\n", __FUNCTION__, StreamDescriptionToString(desc, formatString), i, currentScore);
203 if (currentScore > highestScore)
206 highestScore = currentScore;
213 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InStereoWithPassthroughFormats)
215 unsigned int formatIdx = 0;
218 //try to match the stream formats for ac3
219 AEAudioFormat srcFormat = getAC3AEFormat();
220 // mach ac3 in streamformats with dedicated passthrough format
221 formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
222 EXPECT_EQ(formatIdx, stereoFormatsWithoutPassthrough.size() + 1);
225 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InStereoWithoutPassthroughFormats)
227 unsigned int formatIdx = 0;
230 //try to match the stream formats for ac3
231 AEAudioFormat srcFormat = getAC3AEFormat();
232 //match ac3 in streamformats without dedicated passthrough format (bitstream)
233 formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
234 EXPECT_EQ(formatIdx, (unsigned int)1);
237 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InAllWithPassthroughFormats)
239 unsigned int formatIdx = 0;
242 //try to match the stream formats for ac3
243 AEAudioFormat srcFormat = getAC3AEFormat();
244 // mach ac3 in streamformats with dedicated passthrough format
245 formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
246 EXPECT_EQ(formatIdx,allFormatsWithoutPassthrough.size() + 1);
249 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InAllWithoutPassthroughFormats)
251 unsigned int formatIdx = 0;
254 //try to match the stream formats for ac3
255 AEAudioFormat srcFormat = getAC3AEFormat();
256 //match ac3 in streamformats without dedicated passthrough format (bitstream)
257 formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
258 EXPECT_EQ(formatIdx, (unsigned int)1);
261 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InStereoWithPassthroughFormats)
263 unsigned int formatIdx = 0;
266 // match stereo float 22050hz
267 AEAudioFormat srcFormat = getStereo22050AEFormat();
268 formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
269 EXPECT_EQ(formatIdx, (unsigned int)8);
273 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InStereoWithoutPassthroughFormats)
275 unsigned int formatIdx = 0;
278 // match stereo float 22050hz
279 AEAudioFormat srcFormat = getStereo22050AEFormat();
281 formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
282 EXPECT_EQ(formatIdx, (unsigned int)8);
285 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InAllWithPassthroughFormats)
287 unsigned int formatIdx = 0;
290 // match stereo float 22050hz
291 AEAudioFormat srcFormat = getStereo22050AEFormat();
292 formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
293 EXPECT_EQ(formatIdx, (unsigned int)8);
297 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InAllWithoutPassthroughFormats)
299 unsigned int formatIdx = 0;
302 // match stereo float 22050hz
303 AEAudioFormat srcFormat = getStereo22050AEFormat();
305 formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
306 EXPECT_EQ(formatIdx, (unsigned int)8);
309 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InStereoWithPassthroughFormats)
311 unsigned int formatIdx = 0;
314 // match stereo float 48000hz
315 AEAudioFormat srcFormat = getStereo48000AEFormat();
316 formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
317 EXPECT_EQ(formatIdx, (unsigned int)7);
321 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InStereoWithoutPassthroughFormats)
323 unsigned int formatIdx = 0;
326 // match stereo float 48000hz
327 AEAudioFormat srcFormat = getStereo48000AEFormat();
329 formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
330 EXPECT_EQ(formatIdx, (unsigned int)7);
333 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InAllWithPassthroughFormats)
335 unsigned int formatIdx = 0;
338 // match stereo float 48000hz
339 AEAudioFormat srcFormat = getStereo48000AEFormat();
340 formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
341 EXPECT_EQ(formatIdx, (unsigned int)7);
345 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InAllWithoutPassthroughFormats)
347 unsigned int formatIdx = 0;
350 // match stereo float 48000hz
351 AEAudioFormat srcFormat = getStereo48000AEFormat();
353 formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
354 EXPECT_EQ(formatIdx, (unsigned int)7);
357 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InStereoWithPassthroughFormats)
359 unsigned int formatIdx = 0;
362 // match lpcm float 96000hz
363 AEAudioFormat srcFormat = getLPCM96000AEFormat();
364 formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
365 EXPECT_EQ(formatIdx, (unsigned int)6);
369 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InStereoWithoutPassthroughFormats)
371 unsigned int formatIdx = 0;
374 // match lpcm float 96000hz
375 AEAudioFormat srcFormat = getLPCM96000AEFormat();
377 formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
378 EXPECT_EQ(formatIdx, (unsigned int)6);
381 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InAllWithPassthroughFormats)
383 unsigned int formatIdx = 0;
386 // match lpcm float 96000hz
387 AEAudioFormat srcFormat = getLPCM96000AEFormat();
388 formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
389 EXPECT_EQ(formatIdx, (unsigned int)15);
393 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InAllWithoutPassthroughFormats)
395 unsigned int formatIdx = 0;
398 // match lpcm float 96000hz
399 AEAudioFormat srcFormat = getLPCM96000AEFormat();
401 formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
402 EXPECT_EQ(formatIdx, (unsigned int)15);
404 #endif //TARGET_DARWIN_OSX