VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp@ 54483

Last change on this file since 54483 was 54483, checked in by vboxsync, 10 years ago

Whops.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1/* $Id: tstAudioMixBuffer.cpp 54483 2015-02-25 12:02:44Z vboxsync $ */
2/** @file
3 * Audio testcase - Mixing buffer.
4 */
5
6/*
7 * Copyright (C) 2014-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/err.h>
23#include <iprt/initterm.h>
24#include <iprt/mem.h>
25#include <iprt/rand.h>
26#include <iprt/stream.h>
27#include <iprt/string.h>
28#include <iprt/test.h>
29
30
31#include "../AudioMixBuffer.h"
32#include "../DrvAudio.h"
33
34
35/*******************************************************************************
36* Structures and Typedefs *
37*******************************************************************************/
38
39static int tstSingle(RTTEST hTest)
40{
41 RTTestSubF(hTest, "Single buffer");
42
43 PDMAUDIOSTREAMCFG config =
44 {
45 44100, /* Hz */
46 2 /* Channels */,
47 AUD_FMT_S16 /* Format */,
48 PDMAUDIOENDIANESS_LITTLE /* Endianess */
49 };
50 PDMPCMPROPS props;
51
52 int rc = drvAudioStreamCfgToProps(&config, &props);
53 AssertRC(rc);
54
55 uint32_t cBufSize = _1K;
56
57 /*
58 * General stuff.
59 */
60 PDMAUDIOMIXBUF mb;
61 RTTESTI_CHECK_RC_OK(audioMixBufInit(&mb, "Single", &props, cBufSize));
62 RTTESTI_CHECK(audioMixBufSize(&mb) == cBufSize);
63 RTTESTI_CHECK(AUDIOMIXBUF_B2S(&mb, audioMixBufSizeBytes(&mb)) == cBufSize);
64 RTTESTI_CHECK(AUDIOMIXBUF_S2B(&mb, audioMixBufSize(&mb)) == audioMixBufSizeBytes(&mb));
65 RTTESTI_CHECK(audioMixBufFree(&mb) == cBufSize);
66 RTTESTI_CHECK(AUDIOMIXBUF_S2B(&mb, audioMixBufFree(&mb)) == audioMixBufFreeBytes(&mb));
67
68 /*
69 * Absolute writes.
70 */
71 uint32_t read = 0, written = 0, written_abs = 0;
72 int8_t samples8 [2] = { 0x12, 0x34 };
73 int16_t samples16[2] = { 0xAA, 0xBB };
74 int32_t samples32[2] = { 0xCC, 0xDD };
75 int64_t samples64[2] = { 0xEE, 0xFF };
76
77 RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&mb, 0, &samples8, sizeof(samples8), &written));
78 RTTESTI_CHECK(written == 0 /* Samples */);
79
80 RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&mb, 0, &samples16, sizeof(samples16), &written));
81 RTTESTI_CHECK(written == 1 /* Samples */);
82
83 RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&mb, 2, &samples32, sizeof(samples32), &written));
84 RTTESTI_CHECK(written == 2 /* Samples */);
85 written_abs = 0;
86
87 /* Beyond buffer. */
88 RTTESTI_CHECK_RC(audioMixBufWriteAt(&mb, audioMixBufSize(&mb) + 1, &samples16, sizeof(samples16),
89 &written), VERR_BUFFER_OVERFLOW);
90
91 /*
92 * Circular writes.
93 */
94 size_t cToWrite = audioMixBufSize(&mb) - written_abs - 1; /* -1 as padding plus -2 samples for above. */
95 for (size_t i = 0; i < cToWrite; i++)
96 {
97 RTTESTI_CHECK_RC_OK(audioMixBufWriteCirc(&mb, &samples16, sizeof(samples16), &written));
98 RTTESTI_CHECK(written == 1);
99 }
100 RTTESTI_CHECK(!audioMixBufIsEmpty(&mb));
101 RTTESTI_CHECK(audioMixBufFree(&mb) == 1);
102 RTTESTI_CHECK(audioMixBufFreeBytes(&mb) == AUDIOMIXBUF_S2B(&mb, 1));
103 RTTESTI_CHECK(audioMixBufProcessed(&mb) == cToWrite + written_abs /* + last absolute write */);
104
105 RTTESTI_CHECK_RC_OK(audioMixBufWriteCirc(&mb, &samples16, sizeof(samples16), &written));
106 RTTESTI_CHECK(written == 1);
107 RTTESTI_CHECK(audioMixBufFree(&mb) == 0);
108 RTTESTI_CHECK(audioMixBufFreeBytes(&mb) == AUDIOMIXBUF_S2B(&mb, 0));
109 RTTESTI_CHECK(audioMixBufProcessed(&mb) == cBufSize);
110
111 /* Circular reads. */
112 size_t cToRead = audioMixBufSize(&mb) - written_abs - 1;
113 for (size_t i = 0; i < cToWrite; i++)
114 {
115 RTTESTI_CHECK_RC_OK(audioMixBufReadCirc(&mb, &samples16, sizeof(samples16), &read));
116 RTTESTI_CHECK(read == 1);
117 audioMixBufFinish(&mb, read);
118 }
119 RTTESTI_CHECK(!audioMixBufIsEmpty(&mb));
120 RTTESTI_CHECK(audioMixBufFree(&mb) == audioMixBufSize(&mb) - written_abs - 1);
121 RTTESTI_CHECK(audioMixBufFreeBytes(&mb) == AUDIOMIXBUF_S2B(&mb, cBufSize - written_abs - 1));
122 RTTESTI_CHECK(audioMixBufProcessed(&mb) == cBufSize - cToRead + written_abs);
123
124 RTTESTI_CHECK_RC_OK(audioMixBufReadCirc(&mb, &samples16, sizeof(samples16), &read));
125 RTTESTI_CHECK(read == 1);
126 audioMixBufFinish(&mb, read);
127 RTTESTI_CHECK(audioMixBufFree(&mb) == cBufSize - written_abs);
128 RTTESTI_CHECK(audioMixBufFreeBytes(&mb) == AUDIOMIXBUF_S2B(&mb, cBufSize - written_abs));
129 RTTESTI_CHECK(audioMixBufProcessed(&mb) == written_abs);
130
131 return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
132}
133
134static int tstParentChild(RTTEST hTest)
135{
136 RTTestSubF(hTest, "2 Children -> Parent");
137
138 uint32_t cBufSize = _1K;
139
140 PDMAUDIOSTREAMCFG cfg_p =
141 {
142 44100, /* Hz */
143 2 /* Channels */,
144 AUD_FMT_S16 /* Format */,
145 PDMAUDIOENDIANESS_LITTLE /* Endianess */
146 };
147 PDMPCMPROPS props;
148
149 int rc = drvAudioStreamCfgToProps(&cfg_p, &props);
150 AssertRC(rc);
151
152 PDMAUDIOMIXBUF parent;
153 RTTESTI_CHECK_RC_OK(audioMixBufInit(&parent, "Parent", &props, cBufSize));
154
155 PDMAUDIOSTREAMCFG cfg_c1 = /* Upmixing to parent */
156 {
157 22100, /* Hz */
158 2 /* Channels */,
159 AUD_FMT_S16 /* Format */,
160 PDMAUDIOENDIANESS_LITTLE /* Endianess */
161 };
162
163 rc = drvAudioStreamCfgToProps(&cfg_c1, &props);
164 AssertRC(rc);
165
166 PDMAUDIOMIXBUF child1;
167 RTTESTI_CHECK_RC_OK(audioMixBufInit(&child1, "Child1", &props, cBufSize));
168 RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child1, &parent));
169
170 PDMAUDIOSTREAMCFG cfg_c2 = /* Downmixing to parent */
171 {
172 48000, /* Hz */
173 2 /* Channels */,
174 AUD_FMT_S16 /* Format */,
175 PDMAUDIOENDIANESS_LITTLE /* Endianess */
176 };
177
178 rc = drvAudioStreamCfgToProps(&cfg_c2, &props);
179 AssertRC(rc);
180
181 PDMAUDIOMIXBUF child2;
182 RTTESTI_CHECK_RC_OK(audioMixBufInit(&child2, "Child2", &props, cBufSize));
183 RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child2, &parent));
184
185 /*
186 * Writing + mixing from child/children -> parent, sequential.
187 */
188 size_t cbBuf = _1K;
189 char pvBuf[_1K];
190 int16_t samples[32] = { 0xAA, 0xBB };
191 uint32_t free, read , written, proc, mixed, temp;
192
193 uint32_t cChild1Free = cBufSize;
194 uint32_t cChild1Mixed = 0;
195 uint32_t cSamplesParent1 = 16;
196 uint32_t cSamplesChild1 = 16;
197
198 uint32_t cChild2Free = cBufSize;
199 uint32_t cChild2Mixed = 0;
200 uint32_t cSamplesParent2 = 16;
201 uint32_t cSamplesChild2 = 16;
202
203 uint32_t t = RTRandU32() % 64;
204
205 for (uint32_t i = 0; i < t; i++)
206 {
207 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "i=%RU32\n", i);
208 RTTESTI_CHECK_RC_OK_BREAK(audioMixBufWriteAt(&child1, 0, &samples, sizeof(samples), &written));
209 RTTESTI_CHECK_MSG_BREAK(written == cSamplesChild1, ("Child1: Expected %RU32 written samples, got %RU32\n", cSamplesChild1, written));
210 RTTESTI_CHECK_RC_OK_BREAK(audioMixBufMixToParent(&child1, written, &mixed));
211 temp = audioMixBufProcessed(&parent) - audioMixBufMixed(&child2);
212 RTTESTI_CHECK_MSG_BREAK(audioMixBufMixed(&child1) == temp, ("Child1: Expected %RU32 mixed samples, got %RU32\n", audioMixBufMixed(&child1), temp));
213
214 RTTESTI_CHECK_RC_OK_BREAK(audioMixBufWriteAt(&child2, 0, &samples, sizeof(samples), &written));
215 RTTESTI_CHECK_MSG_BREAK(written == cSamplesChild2, ("Child2: Expected %RU32 written samples, got %RU32\n", cSamplesChild2, written));
216 RTTESTI_CHECK_RC_OK_BREAK(audioMixBufMixToParent(&child2, written, &mixed));
217 temp = audioMixBufProcessed(&parent) - audioMixBufMixed(&child1);
218 RTTESTI_CHECK_MSG_BREAK(audioMixBufMixed(&child2) == temp, ("Child2: Expected %RU32 mixed samples, got %RU32\n", audioMixBufMixed(&child2), temp));
219 }
220
221 RTTESTI_CHECK(audioMixBufProcessed(&parent) == audioMixBufMixed(&child1) + audioMixBufMixed(&child2));
222
223 for (;;)
224 {
225 RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, pvBuf, cbBuf, &read));
226 if (!read)
227 break;
228 audioMixBufFinish(&parent, read);
229 }
230
231 RTTESTI_CHECK(audioMixBufProcessed(&parent) == 0);
232 RTTESTI_CHECK(audioMixBufMixed(&child1) == 0);
233 RTTESTI_CHECK(audioMixBufMixed(&child2) == 0);
234
235 return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
236}
237
238int main(int argc, char **argv)
239{
240 RTR3InitExe(argc, &argv, 0);
241
242 /*
243 * Initialize IPRT and create the test.
244 */
245 RTTEST hTest;
246 int rc = RTTestInitAndCreate("tstAudioMixBuffer", &hTest);
247 if (rc)
248 return rc;
249 RTTestBanner(hTest);
250
251 rc = tstSingle(hTest);
252 if (RT_SUCCESS(rc))
253 rc = tstParentChild(hTest);
254
255 /*
256 * Summary
257 */
258 return RTTestSummaryAndDestroy(hTest);
259}
260
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette