summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Audio/HDAStreamPeriod.h
blob: a782a3bc18baa28118797b846cc1769235df2def (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* $Id: HDAStreamPeriod.h $ */
/** @file
 * HDAStreamPeriod.h - Stream period functions for HD Audio.
 */

/*
 * Copyright (C) 2017-2019 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#ifndef VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h
#define VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <iprt/critsect.h>
#ifdef DEBUG
# include <iprt/time.h>
#endif
#include <VBox/log.h> /* LOG_ENABLED */

struct HDASTREAM;
typedef HDASTREAM *PHDASTREAM;

#ifdef LOG_ENABLED
/**
 * Structure for debug information of an HDA stream's period.
 */
typedef struct HDASTREAMPERIODDBGINFO
{
    /** Host start time (in ns) of the period. */
    uint64_t                tsStartNs;
} HDASTREAMPERIODDBGINFO, *PHDASTREAMPERIODDBGINFO;
#endif

/** No flags set. */
#define HDASTREAMPERIOD_FLAG_NONE    0
/** The stream period has been initialized and is in a valid state. */
#define HDASTREAMPERIOD_FLAG_VALID   RT_BIT(0)
/** The stream period is active. */
#define HDASTREAMPERIOD_FLAG_ACTIVE  RT_BIT(1)

/**
 * Structure for keeping an HDA stream's (time) period.
 * This is needed in order to keep track of stream timing and interrupt delivery.
 */
typedef struct HDASTREAMPERIOD
{
    /** Critical section for serializing access. */
    RTCRITSECT              CritSect;
    /** Associated HDA stream descriptor (SD) number. */
    uint8_t                 u8SD;
    /** The period's status flags. */
    uint8_t                 fStatus;
    /** Number of pending interrupts required for this period. */
    uint8_t                 cIntPending;
    uint8_t                 bPadding0;
    /** Hertz (Hz) rate this period runs with. */
    uint32_t                u32Hz;
    /** Period start time (in wall clock counts). */
    uint64_t                u64StartWalClk;
    /** Period duration (in wall clock counts). */
    uint64_t                u64DurationWalClk;
    /** The period's (relative) elapsed time (in wall clock counts). */
    uint64_t                u64ElapsedWalClk;
    /** Delay (in wall clock counts) for tweaking the period timing. Optional. */
    int64_t                 i64DelayWalClk;
    /** Number of audio frames to transfer for this period. */
    uint32_t                framesToTransfer;
    /** Number of audio frames already transfered. */
    uint32_t                framesTransferred;
#ifdef LOG_ENABLED
    /** Debugging information. */
    HDASTREAMPERIODDBGINFO  Dbg;
#endif
} HDASTREAMPERIOD;
AssertCompileSizeAlignment(HDASTREAMPERIOD, 8);
/** Pointer to a HDA stream's time period keeper. */
typedef HDASTREAMPERIOD *PHDASTREAMPERIOD;

#ifdef IN_RING3
int      hdaR3StreamPeriodCreate(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodDestroy(PHDASTREAMPERIOD pPeriod);
int      hdaR3StreamPeriodInit(PHDASTREAMPERIOD pPeriod, uint8_t u8SD, uint16_t u16LVI, uint32_t u32CBL, PPDMAUDIOSTREAMCFG pStreamCfg);
void     hdaR3StreamPeriodReset(PHDASTREAMPERIOD pPeriod);
int      hdaR3StreamPeriodBegin(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk);
void     hdaR3StreamPeriodEnd(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodPause(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodResume(PHDASTREAMPERIOD pPeriod);
bool     hdaR3StreamPeriodLock(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodUnlock(PHDASTREAMPERIOD pPeriod);
uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t uFrames);
uint64_t hdaR3StreamPeriodGetAbsEndWalClk(PHDASTREAMPERIOD pPeriod);
uint64_t hdaR3StreamPeriodGetAbsElapsedWalClk(PHDASTREAMPERIOD pPeriod);
uint32_t hdaR3StreamPeriodGetRemainingFrames(PHDASTREAMPERIOD pPeriod);
bool     hdaR3StreamPeriodHasElapsed(PHDASTREAMPERIOD pPeriod);
bool     hdaR3StreamPeriodHasPassedAbsWalClk(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk);
bool     hdaR3StreamPeriodNeedsInterrupt(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodAcquireInterrupt(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodReleaseInterrupt(PHDASTREAMPERIOD pPeriod);
void     hdaR3StreamPeriodInc(PHDASTREAMPERIOD pPeriod, uint32_t framesInc);
bool     hdaR3StreamPeriodIsComplete(PHDASTREAMPERIOD pPeriod);
#endif /* IN_RING3 */

#endif /* !VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h */