VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/AudioTest.h@ 98523

Last change on this file since 98523 was 98103, checked in by vboxsync, 22 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.1 KB
Line 
1/* $Id: AudioTest.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Audio testing routines.
4 * Common code which is being used by the ValidationKit audio test (VKAT)
5 * and the debug / ValdikationKit audio driver(s).
6 */
7
8/*
9 * Copyright (C) 2021-2023 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * SPDX-License-Identifier: GPL-3.0-only
28 */
29
30#ifndef VBOX_INCLUDED_SRC_Audio_AudioTest_h
31#define VBOX_INCLUDED_SRC_Audio_AudioTest_h
32#ifndef RT_WITHOUT_PRAGMA_ONCE
33# pragma once
34#endif
35
36/** @todo Some stuff here can be private-only to the implementation. */
37
38/** Maximum length in characters an audio test tag can have. */
39#define AUDIOTEST_TAG_MAX 64
40/** Maximum length in characters a single audio test error description can have. */
41#define AUDIOTEST_ERROR_DESC_MAX 256
42/** Prefix for audio test (set) directories. */
43#define AUDIOTEST_PATH_PREFIX_STR "vkat"
44/** Maximum tests a beacon can have.
45 * Maximum number of tests is 240 (so it can fit into 8-bit mono channels). */
46#define AUDIOTEST_BEACON_TESTS_MAX 240
47/** Returns a pre-beacon for a given test number.
48 * Maximum number of tests is 240 (so it can fit into 8-bit mono channels).
49 *
50 * That way it's easy to visually inspect beacon data in a hex editor --
51 * e.g. for test #5 a pre-beacon would be 0x5A + post-beacon 0x5B. */
52#define AUDIOTEST_BEACON_MAKE_PRE(a_TstNum) \
53 ( (uint8_t)((a_TstNum) & 0xf) << 4 \
54 | (uint8_t)(0xA))
55/** Returns a post-beacon for a given test number.
56 * Maximum number of tests is 250 (so it can fit into 8-bit mono channels).
57 *
58 * That way it's easy to visually inspect beacon data in a hex editor --
59 * e.g. for test #2 a pre-beacon would be 0x2A + post-beacon 0x2B. */
60#define AUDIOTEST_BEACON_MAKE_POST(a_TstNum) \
61 ( (uint8_t)((a_TstNum) & 0xf) << 4 \
62 | (uint8_t)(0xB))
63/** Pre / post audio beacon size (in audio frames). */
64#define AUDIOTEST_BEACON_SIZE_FRAMES 1024
65
66/**
67 * Enumeration for an audio test tone (wave) type.
68 */
69typedef enum AUDIOTESTTONETYPE
70{
71 /** Invalid type. */
72 AUDIOTESTTONETYPE_INVALID = 0,
73 /** Sine wave. */
74 AUDIOTESTTONETYPE_SINE,
75 /** Square wave. Not implemented yet. */
76 AUDIOTESTTONETYPE_SQUARE,
77 /** Triangluar wave. Not implemented yet. */
78 AUDIOTESTTONETYPE_TRIANGLE,
79 /** Sawtooth wave. Not implemented yet. */
80 AUDIOTESTTONETYPE_SAWTOOTH,
81 /** The usual 32-bit hack. */
82 AUDIOTESTTONETYPE_32BIT_HACK = 0x7fffffff
83} AUDIOTESTTONETYPE;
84
85/**
86 * Structure for handling an audio (sine wave) test tone.
87 */
88typedef struct AUDIOTESTTONE
89{
90 /** The tone's wave type. */
91 AUDIOTESTTONETYPE enmType;
92 /** The PCM properties. */
93 PDMAUDIOPCMPROPS Props;
94 /** Current sample index for generate the sine wave. */
95 uint64_t uSample;
96 /** The fixed portion of the sin() input. */
97 double rdFixed;
98 /** Frequency (in Hz) of the sine wave to generate. */
99 double rdFreqHz;
100} AUDIOTESTTONE;
101/** Pointer to an audio test tone. */
102typedef AUDIOTESTTONE *PAUDIOTESTTONE;
103
104/**
105 * Structure for a common test parameters header.
106 */
107typedef struct AUDIOTESTPARMSHDR
108{
109 /** Test index these test parameters belong to.
110 * Set to UINT32_MAX if not being used. */
111 uint32_t idxTest;
112 /** Time of the caller when this test was being created. */
113 RTTIME tsCreated;
114} AUDIOTESTPARMSHDR;
115/** Pointer to an audio test tone. */
116typedef AUDIOTESTPARMSHDR *PAUDIOTESTPARMSHDR;
117
118/**
119 * Structure for handling audio test tone parameters.
120 */
121typedef struct AUDIOTESTTONEPARMS
122{
123 /** Common test header. */
124 AUDIOTESTPARMSHDR Hdr;
125 /** The PCM properties. */
126 PDMAUDIOPCMPROPS Props;
127 /** Tone frequency (in Hz) to use.
128 * Will be later converted to a double value. */
129 double dbFreqHz;
130 /** Prequel (in ms) to play silence. Optional and can be set to 0. */
131 RTMSINTERVAL msPrequel;
132 /** Duration (in ms) to play the test tone. */
133 RTMSINTERVAL msDuration;
134 /** Sequel (in ms) to play silence. Optional and can be set to 0. */
135 RTMSINTERVAL msSequel;
136 /** Volume (in percent, 0-100) to use.
137 * If set to 0, the tone is muted (i.e. silent). */
138 uint8_t uVolumePercent;
139} AUDIOTESTTONEPARMS;
140/** Pointer to audio test tone parameters. */
141typedef AUDIOTESTTONEPARMS *PAUDIOTESTTONEPARMS;
142
143/**
144 * Enumeration defining an audio test beacon type.
145 */
146typedef enum AUDIOTESTTONEBEACONTYPE
147{
148 /** Invalid type. */
149 AUDIOTESTTONEBEACONTYPE_INVALID = 0,
150 /** Playback beacon (pre). */
151 AUDIOTESTTONEBEACONTYPE_PLAY_PRE = 1,
152 /** Playback beacon (post). */
153 AUDIOTESTTONEBEACONTYPE_PLAY_POST = 2,
154 /** Recording beacon (pre). */
155 AUDIOTESTTONEBEACONTYPE_REC_PRE = 3,
156 /** Recording beacon (post). */
157 AUDIOTESTTONEBEACONTYPE_REC_POST = 4,
158 /** The usual 32-bit hack. */
159 OTESTTONEBEACONTYPE_32BIT_HACK = 0x7fffffff
160} AUDIOTESTTONEBEACONTYPE;
161
162/**
163 * Structure defining an audio test tone beacon.
164 *
165 * This is being used for (optionally) marking beginning/ending of audio test data.
166 */
167typedef struct AUDIOTESTTONEBEACON
168{
169 /** Test number this beacon is for. */
170 uint8_t uTest;
171 /** The beacon type. */
172 AUDIOTESTTONEBEACONTYPE enmType;
173 /** PCM properties to use for this beacon. */
174 PDMAUDIOPCMPROPS Props;
175 /** Beacon bytes to process.
176 * When doing test tone playback: Beacon bytes to write.
177 * When doing test tone recording: Beacon bytes to read. */
178 uint32_t cbSize;
179 /** Beacon bytes already processed.
180 * When doing test tone playback: Beacon bytes written.
181 * When doing test tone recording: Beacon bytes read. */
182 uint32_t cbUsed;
183} AUDIOTESTTONEBEACON;
184/** Pointer to audio test tone beacon. */
185typedef AUDIOTESTTONEBEACON *PAUDIOTESTTONEBEACON;
186/** Pointer (const) to audio test tone beacon. */
187typedef AUDIOTESTTONEBEACON const *PCAUDIOTESTTONEBEACON;
188
189/**
190 * Enumeration for the test set mode.
191 */
192typedef enum AUDIOTESTSETMODE
193{
194 /** Invalid test set mode. */
195 AUDIOTESTSETMODE_INVALID = 0,
196 /** Test set is being created (testing in progress). */
197 AUDIOTESTSETMODE_TEST,
198 /** Existing test set is being verified. */
199 AUDIOTESTSETMODE_VERIFY,
200 /** The usual 32-bit hack. */
201 AUDIOTESTSETMODE_32BIT_HACK = 0x7fffffff
202} AUDIOTESTSETMODE;
203
204/**
205 * Enumeration to specify an audio test type.
206 */
207typedef enum AUDIOTESTTYPE
208{
209 /** Invalid test type, do not use. */
210 AUDIOTESTTYPE_INVALID = 0,
211 /** Play a test tone. */
212 AUDIOTESTTYPE_TESTTONE_PLAY,
213 /** Record a test tone. */
214 AUDIOTESTTYPE_TESTTONE_RECORD,
215 /** The usual 32-bit hack. */
216 AUDIOTESTTYPE_32BIT_HACK = 0x7fffffff
217} AUDIOTESTTYPE;
218
219/**
220 * Audio test request data.
221 */
222typedef struct AUDIOTESTPARMS
223{
224 /** Audio device to use. */
225 PDMAUDIOHOSTDEV Dev;
226 /** How much to delay (wait, in ms) the test being executed. */
227 RTMSINTERVAL msDelay;
228 /** The test direction. */
229 PDMAUDIODIR enmDir;
230 /** The test type. */
231 AUDIOTESTTYPE enmType;
232 /** Union for test type-specific data. */
233 union
234 {
235 AUDIOTESTTONEPARMS TestTone;
236 };
237} AUDIOTESTPARMS;
238/** Pointer to a test parameter structure. */
239typedef AUDIOTESTPARMS *PAUDIOTESTPARMS;
240
241/** Test object handle. */
242typedef R3R0PTRTYPE(struct AUDIOTESTOBJINT RT_FAR *) AUDIOTESTOBJ;
243/** Pointer to test object handle. */
244typedef AUDIOTESTOBJ RT_FAR *PAUDIOTESTOBJ;
245/** Nil test object handle. */
246#define NIL_AUDIOTESTOBJ ((AUDIOTESTOBJ)~(RTHCINTPTR)0)
247
248struct AUDIOTESTSET;
249
250/**
251 * Structure specifying a single audio test entry of a test set.
252 *
253 * A test set can contain zero or more test entry (tests).
254 */
255typedef struct AUDIOTESTENTRY
256{
257 /** List node. */
258 RTLISTNODE Node;
259 /** Pointer to test set parent. */
260 AUDIOTESTSET *pParent;
261 /** Friendly description of the test. */
262 char szDesc[64];
263 /** Audio test parameters this test needs to perform the actual test. */
264 AUDIOTESTPARMS Parms;
265 /** Number of test objects bound to this test. */
266 uint32_t cObj;
267 /** Absolute offset (in bytes) where to write the "obj_count" value later. */
268 uint64_t offObjCount;
269 /** Overall test result. */
270 int rc;
271} AUDIOTESTENTRY;
272/** Pointer to an audio test entry. */
273typedef AUDIOTESTENTRY *PAUDIOTESTENTRY;
274
275/**
276 * Structure specifying an audio test set.
277 */
278typedef struct AUDIOTESTSET
279{
280 /** The set's tag. */
281 char szTag[AUDIOTEST_TAG_MAX];
282 /** Absolute path where to store the test audio data. */
283 char szPathAbs[RTPATH_MAX];
284 /** Current mode the test set is in. */
285 AUDIOTESTSETMODE enmMode;
286 union
287 {
288 /** @todo r=bird: RTSTREAM not RTFILE. That means you don't have to check
289 * every write status code and it's buffered and thus faster. Also,
290 * you don't have to re-invent fprintf-style RTFileWrite wrappers. */
291 RTFILE hFile;
292 RTINIFILE hIniFile;
293 } f;
294 /** Number of test objects in lstObj. */
295 uint32_t cObj;
296 /** Absolute offset (in bytes) where to write the "obj_count" value later. */
297 uint64_t offObjCount;
298 /** List containing PAUDIOTESTOBJ test object entries. */
299 RTLISTANCHOR lstObj;
300 /** Number of performed tests.
301 * Not necessarily bound to the test object entries above. */
302 uint32_t cTests;
303 /** Absolute offset (in bytes) where to write the "test_count" value later. */
304 uint64_t offTestCount;
305 /** List containing PAUDIOTESTENTRY test entries. */
306 RTLISTANCHOR lstTest;
307 /** Current test running. Can be NULL if no test is running. */
308 PAUDIOTESTENTRY pTestCur;
309 /** Number of tests currently running.
310 * Currently we only allow one concurrent test running at a given time. */
311 uint32_t cTestsRunning;
312 /** Number of total (test) failures. */
313 uint32_t cTotalFailures;
314} AUDIOTESTSET;
315/** Pointer to an audio test set. */
316typedef AUDIOTESTSET *PAUDIOTESTSET;
317
318/**
319 * Audio test verification options.
320 */
321typedef struct AUDIOTESTVERIFYOPTS
322{
323 /** Flag indicating whether to keep going after an error has occurred. */
324 bool fKeepGoing;
325 /** Whether to perform audio normalization or not. */
326 bool fNormalize;
327 /** Threshold of file differences (number of chunks) at when we consider audio files
328 * as not matching. 0 means an exact match. */
329 uint32_t cMaxDiff;
330 /** Threshold of file differences (difference in percent) at when we consider audio files
331 * as not matching. 0 means an exact match. */
332 uint8_t uMaxDiffPercent;
333 /** Threshold of file size (+/-, in percent) at when we consider audio files
334 * as not matching. 0 means an exact match.*/
335 uint8_t uMaxSizePercent;
336 /** Search window (in ms) to use for treating / classifying audio data. */
337 uint32_t msSearchWindow;
338} AUDIOTESTVERIFYOPTS;
339/** Pointer to audio test verification options. */
340typedef AUDIOTESTVERIFYOPTS *PAUDIOTESTVERIFYOPTS;
341
342/**
343 * Structure for holding a single audio test error entry.
344 */
345typedef struct AUDIOTESTERRORENTRY
346{
347 /** The entrie's list node. */
348 RTLISTNODE Node;
349 /** Additional rc. */
350 int rc;
351 /** Actual error description. */
352 char szDesc[AUDIOTEST_ERROR_DESC_MAX];
353} AUDIOTESTERRORENTRY;
354/** Pointer to an audio test error description. */
355typedef AUDIOTESTERRORENTRY *PAUDIOTESTERRORENTRY;
356
357/**
358 * Structure for holding an audio test error description.
359 * This can contain multiple errors (FIFO list).
360 */
361typedef struct AUDIOTESTERRORDESC
362{
363 /** List entries containing the (FIFO-style) errors of type AUDIOTESTERRORENTRY. */
364 RTLISTANCHOR List;
365 /** Number of errors in the list. */
366 uint32_t cErrors;
367} AUDIOTESTERRORDESC;
368/** Pointer to an audio test error description. */
369typedef AUDIOTESTERRORDESC *PAUDIOTESTERRORDESC;
370/** Const pointer to an audio test error description. */
371typedef AUDIOTESTERRORDESC const *PCAUDIOTESTERRORDESC;
372
373/**
374 * Enumeration specifying an internal test state.
375 */
376typedef enum AUDIOTESTSTATE
377{
378 /** Test is initializing. */
379 AUDIOTESTSTATE_INIT = 0,
380 /** Test is in pre-run phase. */
381 AUDIOTESTSTATE_PRE,
382 /** Test is running */
383 AUDIOTESTSTATE_RUN,
384 /** Test is in post-run phase. */
385 AUDIOTESTSTATE_POST,
386 /** Test has been run. */
387 AUDIOTESTSTATE_DONE,
388 /** The usual 32-bit hack. */
389 AUDIOTESTSTATE_32BIT_HACK = 0x7fffffff
390} AUDIOTESTSTATE;
391
392double AudioTestToneInit(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps, double dbFreq);
393double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps);
394double AudioTestToneGetRandomFreq(void);
395int AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
396
397void AudioTestBeaconInit(PAUDIOTESTTONEBEACON pBeacon, uint8_t uTest, AUDIOTESTTONEBEACONTYPE enmType, PPDMAUDIOPCMPROPS pProps);
398int AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *auBuf, size_t cbBuf, size_t *pOff);
399int AudioTestBeaconWrite(PAUDIOTESTTONEBEACON pBeacon, void *pvBuf, uint32_t cbBuf);
400uint32_t AudioTestBeaconGetSize(PCAUDIOTESTTONEBEACON pBeacon);
401const char *AudioTestBeaconTypeGetName(AUDIOTESTTONEBEACONTYPE enmType);
402AUDIOTESTTONEBEACONTYPE AudioTestBeaconGetType(PCAUDIOTESTTONEBEACON pBeacon);
403uint32_t AudioTestBeaconGetRemaining(PCAUDIOTESTTONEBEACON pBeacon);
404uint32_t AudioTestBeaconGetUsed(PCAUDIOTESTTONEBEACON pBeacon);
405bool AudioTestBeaconIsComplete(PCAUDIOTESTTONEBEACON pBeacon);
406
407int AudioTestGenTag(char *pszTag, size_t cbTag);
408
409int AudioTestPathGetTemp(char *pszPath, size_t cbPath);
410int AudioTestPathCreateTemp(char *pszPath, size_t cbPath, const char *pszUUID);
411int AudioTestPathCreate(char *pszPath, size_t cbPath, const char *pszUUID);
412
413int AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ pObj);
414
415int AudioTestObjWrite(AUDIOTESTOBJ Obj, const void *pvBuf, size_t cbBuf);
416int AudioTestObjAddMetadataStr(AUDIOTESTOBJ Obj, const char *pszFormat, ...);
417int AudioTestObjClose(AUDIOTESTOBJ Obj);
418
419int AudioTestSetTestBegin(PAUDIOTESTSET pSet, const char *pszDesc, PAUDIOTESTPARMS pParms, PAUDIOTESTENTRY *ppEntry);
420int AudioTestSetTestFailed(PAUDIOTESTENTRY pEntry, int rc, const char *pszErr);
421int AudioTestSetTestDone(PAUDIOTESTENTRY pEntry);
422bool AudioTestSetTestIsRunning(PAUDIOTESTENTRY pEntry);
423
424int AudioTestSetCreate(PAUDIOTESTSET pSet, const char *pszPath, const char *pszTag);
425int AudioTestSetDestroy(PAUDIOTESTSET pSet);
426int AudioTestSetOpen(PAUDIOTESTSET pSet, const char *pszPath);
427int AudioTestSetClose(PAUDIOTESTSET pSet);
428int AudioTestSetWipe(PAUDIOTESTSET pSet);
429const char *AudioTestSetGetTag(PAUDIOTESTSET pSet);
430uint32_t AudioTestSetGetTestsTotal(PAUDIOTESTSET pSet);
431uint32_t AudioTestSetGetTestsRunning(PAUDIOTESTSET pSet);
432uint32_t AudioTestSetGetTotalFailures(PAUDIOTESTSET pSet);
433bool AudioTestSetIsPacked(const char *pszPath);
434bool AudioTestSetIsRunning(PAUDIOTESTSET pSet);
435int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName);
436int AudioTestSetUnpack(const char *pszFile, const char *pszOutDir);
437
438void AudioTestSetVerifyOptsInitStrict(PAUDIOTESTVERIFYOPTS pOpts);
439void AudioTestSetVerifyOptsInit(PAUDIOTESTVERIFYOPTS pOpts);
440bool AudioTestSetVerifyOptsAreEqual(PAUDIOTESTVERIFYOPTS pOptsA, PAUDIOTESTVERIFYOPTS pOptsB);
441
442int AudioTestSetVerify(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTERRORDESC pErrDesc);
443int AudioTestSetVerifyEx(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTVERIFYOPTS pOpts, PAUDIOTESTERRORDESC pErrDesc);
444
445uint32_t AudioTestErrorDescCount(PCAUDIOTESTERRORDESC pErr);
446bool AudioTestErrorDescFailed(PCAUDIOTESTERRORDESC pErr);
447
448void AudioTestErrorDescDestroy(PAUDIOTESTERRORDESC pErr);
449
450const char *AudioTestStateToStr(AUDIOTESTSTATE enmState);
451
452/** @name Wave File Accessors
453 * @{ */
454/**
455 * An open wave (.WAV) file.
456 */
457typedef struct AUDIOTESTWAVEFILE
458{
459 /** Magic value (AUDIOTESTWAVEFILE_MAGIC). */
460 uint32_t u32Magic;
461 /** Set if we're in read-mode, clear if in write mode. */
462 bool fReadMode;
463 /** The file handle. */
464 RTFILE hFile;
465 /** The absolute file offset of the first sample */
466 uint32_t offSamples;
467 /** Number of bytes of samples. */
468 uint32_t cbSamples;
469 /** The current read position relative to @a offSamples. */
470 uint32_t offCur;
471 /** The PCM properties for the file format. */
472 PDMAUDIOPCMPROPS Props;
473} AUDIOTESTWAVEFILE;
474/** Pointer to an open wave file. */
475typedef AUDIOTESTWAVEFILE *PAUDIOTESTWAVEFILE;
476
477/** Magic value for AUDIOTESTWAVEFILE::u32Magic (Miles Dewey Davis III). */
478#define AUDIOTESTWAVEFILE_MAGIC UINT32_C(0x19260526)
479/** Magic value for AUDIOTESTWAVEFILE::u32Magic after closing. */
480#define AUDIOTESTWAVEFILE_MAGIC_DEAD UINT32_C(0x19910928)
481
482int AudioTestWaveFileOpen(const char *pszFile, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo);
483int AudioTestWaveFileCreate(const char *pszFile, PCPDMAUDIOPCMPROPS pProps, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo);
484int AudioTestWaveFileRead(PAUDIOTESTWAVEFILE pWaveFile, void *pvBuf, size_t cbBuf, size_t *pcbRead);
485int AudioTestWaveFileWrite(PAUDIOTESTWAVEFILE pWaveFile, const void *pvBuf, size_t cbBuf);
486int AudioTestWaveFileClose(PAUDIOTESTWAVEFILE pWaveFile);
487
488/** @} */
489
490#endif /* !VBOX_INCLUDED_SRC_Audio_AudioTest_h */
491
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