Merge pull request #4950 from Memphiz/osxfixoptical
[vuplus_xbmc] / xbmc / cores / AudioEngine / Sinks / test / TestAESinkDARWINOSX.cpp
1 /*
2  *      Copyright (C) 2014 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "gtest/gtest.h"
22
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"
27 #include <vector>
28
29 extern float ScoreStream(const AudioStreamBasicDescription &desc, const AEAudioFormat &format);
30
31 std::vector<AudioStreamBasicDescription> stereoFormatsWithPassthrough;
32 std::vector<AudioStreamBasicDescription> stereoFormatsWithoutPassthrough;
33 std::vector<AudioStreamBasicDescription> allFormatsWithPassthrough;
34 std::vector<AudioStreamBasicDescription> allFormatsWithoutPassthrough;
35
36 void addLPCMFormats(std::vector<AudioStreamBasicDescription> &streamFormats)
37 {
38   AudioStreamBasicDescription streamFormat;
39
40   FillOutASBDForLPCM(streamFormat, 96000, 8, 16, 16, false, false, false);
41   streamFormats.push_back(streamFormat); // + 0
42
43   FillOutASBDForLPCM(streamFormat, 48000, 8, 16, 16, false, false, false);
44   streamFormats.push_back(streamFormat); // + 1
45
46   FillOutASBDForLPCM(streamFormat, 44100, 8, 16, 16, false, false, false);
47   streamFormats.push_back(streamFormat); // + 2
48
49   FillOutASBDForLPCM(streamFormat, 96000, 8, 20, 20, false, false, false);
50   streamFormats.push_back(streamFormat); // + 3
51
52   FillOutASBDForLPCM(streamFormat, 48000, 8, 20, 20, false, false, false);
53   streamFormats.push_back(streamFormat); // + 4
54
55   FillOutASBDForLPCM(streamFormat, 44100, 8, 20, 20, false, false, false);
56   streamFormats.push_back(streamFormat); // + 5
57
58   FillOutASBDForLPCM(streamFormat, 96000, 8, 24, 24, false, false, false);
59   streamFormats.push_back(streamFormat); // + 6
60
61   FillOutASBDForLPCM(streamFormat, 48000, 8, 24, 24, false, false, false);
62   streamFormats.push_back(streamFormat); // + 7
63
64   FillOutASBDForLPCM(streamFormat, 44100, 8, 24, 24, false, false, false);
65   streamFormats.push_back(streamFormat); // + 8
66 }
67
68 void addPassthroughFormats(std::vector<AudioStreamBasicDescription> &streamFormats)
69 {
70   AudioStreamBasicDescription streamFormat;
71
72   FillOutASBDForLPCM(streamFormat, 96000, 2, 16, 16, false, false, false);
73   streamFormat.mFormatID = kAudioFormat60958AC3;
74   streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 0
75
76   FillOutASBDForLPCM(streamFormat, 48000, 2, 16, 16, false, false, false);
77   streamFormat.mFormatID = kAudioFormat60958AC3;
78   streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 1
79
80   FillOutASBDForLPCM(streamFormat, 44100, 2, 16, 16, false, false, false);
81   streamFormat.mFormatID = kAudioFormat60958AC3;
82   streamFormats.push_back(streamFormat); // stereoFormtsWithoutPassthrough.size() + 2
83 }
84
85 void initStereoFormatsWithoutPassthrough()
86 {
87   AudioStreamBasicDescription streamFormat;
88   FillOutASBDForLPCM(streamFormat, 96000, 2, 16, 16, false, false, false);
89   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 0
90
91   FillOutASBDForLPCM(streamFormat, 48000, 2, 16, 16, false, false, false);
92   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 1
93
94   FillOutASBDForLPCM(streamFormat, 44100, 2, 16, 16, false, false, false);
95   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 2
96
97   FillOutASBDForLPCM(streamFormat, 96000, 2, 20, 20, false, false, false);
98   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 3
99
100   FillOutASBDForLPCM(streamFormat, 48000, 2, 20, 20, false, false, false);
101   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 4
102
103   FillOutASBDForLPCM(streamFormat, 44100, 2, 20, 20, false, false, false);
104   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 5
105
106   FillOutASBDForLPCM(streamFormat, 96000, 2, 24, 24, false, false, false);
107   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 6
108
109   FillOutASBDForLPCM(streamFormat, 48000, 2, 24, 24, false, false, false);
110   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 7
111
112   FillOutASBDForLPCM(streamFormat, 44100, 2, 24, 24, false, false, false);
113   stereoFormatsWithoutPassthrough.push_back(streamFormat); // 8
114 }
115
116 void initStreamFormats()
117 {
118   stereoFormatsWithPassthrough.clear();
119   stereoFormatsWithoutPassthrough.clear();
120   allFormatsWithPassthrough.clear();
121   allFormatsWithoutPassthrough.clear();
122
123   initStereoFormatsWithoutPassthrough();
124
125   stereoFormatsWithPassthrough = stereoFormatsWithoutPassthrough;
126   allFormatsWithoutPassthrough = stereoFormatsWithoutPassthrough;
127
128   addLPCMFormats( allFormatsWithoutPassthrough);
129
130   allFormatsWithPassthrough = allFormatsWithoutPassthrough;
131
132   addPassthroughFormats(stereoFormatsWithPassthrough);
133   addPassthroughFormats(allFormatsWithPassthrough);
134 }
135
136
137 AEAudioFormat getAC3AEFormat()
138 {
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;
147   return srcFormat;
148 }
149
150 AEAudioFormat getStereo22050AEFormat()
151 {
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;
160   return srcFormat;
161 }
162
163 AEAudioFormat getStereo48000AEFormat()
164 {
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;
173   return srcFormat;
174 }
175
176 AEAudioFormat getLPCM96000AEFormat()
177 {
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;
186   return srcFormat;
187 }
188
189 unsigned int findMatchingFormat(const std::vector<AudioStreamBasicDescription> &formatList, const AEAudioFormat &srcFormat)
190 {
191   unsigned int formatIdx = 0;
192   float highestScore = 0;
193   float currentScore = 0;
194
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++)
197   {
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);
202
203     if (currentScore > highestScore)
204     {
205       formatIdx = i;
206       highestScore = currentScore;
207     }
208   }
209
210   return formatIdx;
211 }
212
213 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InStereoWithPassthroughFormats)
214 {
215   unsigned int formatIdx = 0;
216   initStreamFormats();
217
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);
223 }
224
225 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InStereoWithoutPassthroughFormats)
226 {
227   unsigned int formatIdx = 0;
228   initStreamFormats();
229
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);
235 }
236
237 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InAllWithPassthroughFormats)
238 {
239   unsigned int formatIdx = 0;
240   initStreamFormats();
241
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);
247 }
248
249 TEST(TestAESinkDARWINOSXScoreStream, MatchAc3InAllWithoutPassthroughFormats)
250 {
251   unsigned int formatIdx = 0;
252   initStreamFormats();
253
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);
259 }
260
261 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InStereoWithPassthroughFormats)
262 {
263   unsigned int formatIdx = 0;
264   initStreamFormats();
265
266   // match stereo float 22050hz
267   AEAudioFormat srcFormat = getStereo22050AEFormat();
268   formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
269   EXPECT_EQ(formatIdx, (unsigned int)8);
270 }
271
272
273 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InStereoWithoutPassthroughFormats)
274 {
275   unsigned int formatIdx = 0;
276   initStreamFormats();
277
278   // match stereo float 22050hz
279   AEAudioFormat srcFormat = getStereo22050AEFormat();
280
281   formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
282   EXPECT_EQ(formatIdx, (unsigned int)8);
283 }
284
285 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InAllWithPassthroughFormats)
286 {
287   unsigned int formatIdx = 0;
288   initStreamFormats();
289
290   // match stereo float 22050hz
291   AEAudioFormat srcFormat = getStereo22050AEFormat();
292   formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
293   EXPECT_EQ(formatIdx, (unsigned int)8);
294 }
295
296
297 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo22050InAllWithoutPassthroughFormats)
298 {
299   unsigned int formatIdx = 0;
300   initStreamFormats();
301
302   // match stereo float 22050hz
303   AEAudioFormat srcFormat = getStereo22050AEFormat();
304
305   formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
306   EXPECT_EQ(formatIdx, (unsigned int)8);
307 }
308
309 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InStereoWithPassthroughFormats)
310 {
311   unsigned int formatIdx = 0;
312   initStreamFormats();
313
314   // match stereo float 48000hz
315   AEAudioFormat srcFormat = getStereo48000AEFormat();
316   formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
317   EXPECT_EQ(formatIdx, (unsigned int)7);
318 }
319
320
321 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InStereoWithoutPassthroughFormats)
322 {
323   unsigned int formatIdx = 0;
324   initStreamFormats();
325
326   // match stereo float 48000hz
327   AEAudioFormat srcFormat = getStereo48000AEFormat();
328
329   formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
330   EXPECT_EQ(formatIdx, (unsigned int)7);
331 }
332
333 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InAllWithPassthroughFormats)
334 {
335   unsigned int formatIdx = 0;
336   initStreamFormats();
337
338   // match stereo float 48000hz
339   AEAudioFormat srcFormat = getStereo48000AEFormat();
340   formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
341   EXPECT_EQ(formatIdx, (unsigned int)7);
342 }
343
344
345 TEST(TestAESinkDARWINOSXScoreStream, MatchFloatStereo48000InAllWithoutPassthroughFormats)
346 {
347   unsigned int formatIdx = 0;
348   initStreamFormats();
349
350   // match stereo float 48000hz
351   AEAudioFormat srcFormat = getStereo48000AEFormat();
352
353   formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
354   EXPECT_EQ(formatIdx, (unsigned int)7);
355 }
356
357 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InStereoWithPassthroughFormats)
358 {
359   unsigned int formatIdx = 0;
360   initStreamFormats();
361
362   // match lpcm float 96000hz
363   AEAudioFormat srcFormat = getLPCM96000AEFormat();
364   formatIdx = findMatchingFormat(stereoFormatsWithPassthrough, srcFormat);
365   EXPECT_EQ(formatIdx, (unsigned int)6);
366 }
367
368
369 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InStereoWithoutPassthroughFormats)
370 {
371   unsigned int formatIdx = 0;
372   initStreamFormats();
373
374   // match lpcm float 96000hz
375   AEAudioFormat srcFormat = getLPCM96000AEFormat();
376
377   formatIdx = findMatchingFormat(stereoFormatsWithoutPassthrough, srcFormat);
378   EXPECT_EQ(formatIdx, (unsigned int)6);
379 }
380
381 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InAllWithPassthroughFormats)
382 {
383   unsigned int formatIdx = 0;
384   initStreamFormats();
385
386   // match lpcm float 96000hz
387   AEAudioFormat srcFormat = getLPCM96000AEFormat();
388   formatIdx = findMatchingFormat(allFormatsWithPassthrough, srcFormat);
389   EXPECT_EQ(formatIdx, (unsigned int)15);
390 }
391
392
393 TEST(TestAESinkDARWINOSXScoreStream, MatchFloat5_1_96000InAllWithoutPassthroughFormats)
394 {
395   unsigned int formatIdx = 0;
396   initStreamFormats();
397
398   // match lpcm float 96000hz
399   AEAudioFormat srcFormat = getLPCM96000AEFormat();
400
401   formatIdx = findMatchingFormat(allFormatsWithoutPassthrough, srcFormat);
402   EXPECT_EQ(formatIdx, (unsigned int)15);
403 }
404 #endif //TARGET_DARWIN_OSX