summaryrefslogtreecommitdiff
path: root/audio/SoundWire/Samples/SdcaVad/SdcaVDsp/PositionSimClock.cpp
blob: db0f2aee6c6234865e8690401aa2fc33d68a981b (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*++

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

Module Name:

    PositionSimClock.cpp

Abstract:

    Simulated clock for keeping track of stream position.

Environment:

    Kernel mode

--*/

#include "private.h"
#include "PositionSimClock.h"

#ifndef __INTELLISENSE__
#include "positionsimclock.tmh"
#endif

_Use_decl_annotations_
PAGED_CODE_SEG
CPositionSimClock::CPositionSimClock()
{
    PAGED_CODE();

    m_State = SIM_CLOCK_STATE_STOP;
    m_ElapsedTimeWhenPaused = 0;
    m_StartTime = 0;
    m_QpcTimeStamp = 0;

    KeInitializeSpinLock(&m_Lock);
}

#pragma code_seg()
_Use_decl_annotations_
CPositionSimClock::~CPositionSimClock()
{
}

#pragma code_seg()
_Use_decl_annotations_
void CPositionSimClock::Run()
{
    KIRQL irql = PASSIVE_LEVEL;
    KeAcquireSpinLock(&m_Lock, &irql);

    if (m_State == SIM_CLOCK_STATE_STOP ||
        m_State == SIM_CLOCK_STATE_PAUSE)
    {
        m_StartTime = KeQueryInterruptTimePrecise(&m_QpcTimeStamp);
    }

    m_State = SIM_CLOCK_STATE_RUN;

    DrvLogInfo(g_SDCAVDspLog, FLAG_STREAM, L"CPositionSimClock::Run SIM_CLOCK_STATE_RUN : %lld", m_StartTime);

    KeReleaseSpinLock(&m_Lock, irql);
}

#pragma code_seg()
_Use_decl_annotations_
void CPositionSimClock::Pause()
{
    KIRQL irql = PASSIVE_LEVEL;
    KeAcquireSpinLock(&m_Lock, &irql);

    if (m_State == SIM_CLOCK_STATE_RUN)
    {
        m_ElapsedTimeWhenPaused = GetElapsedTimeUnlocked();
        DrvLogInfo(g_SDCAVDspLog, FLAG_STREAM, L"CPositionSimClock::Pause ElapsedTimeWhenPaused : %lld", m_ElapsedTimeWhenPaused);
    }

    m_State = SIM_CLOCK_STATE_PAUSE;

    KeReleaseSpinLock(&m_Lock, irql);
}

#pragma code_seg()
_Use_decl_annotations_
void CPositionSimClock::Stop()
{
    KIRQL irql = PASSIVE_LEVEL;
    KeAcquireSpinLock(&m_Lock, &irql);

    m_State = SIM_CLOCK_STATE_STOP;
    m_StartTime = 0;
    m_ElapsedTimeWhenPaused = 0;

    DrvLogInfo(g_SDCAVDspLog, FLAG_STREAM, L"CPositionSimClock::Stop");

    KeReleaseSpinLock(&m_Lock, irql);
}

#pragma code_seg()
_Use_decl_annotations_
ULONGLONG CPositionSimClock::GetElapsedTimeUnlocked()
{
    ULONGLONG current_time = KeQueryInterruptTimePrecise(&m_QpcTimeStamp);

    ULONGLONG elapsedTime = (current_time - m_StartTime) + m_ElapsedTimeWhenPaused;

    return elapsedTime;
}

#pragma code_seg()
_Use_decl_annotations_
ULONGLONG CPositionSimClock::GetElapsedTime(PULONGLONG pQpcTimeStamp)
{
    KIRQL irql = PASSIVE_LEVEL;
    KeAcquireSpinLock(&m_Lock, &irql);

    ULONGLONG elapsedTime = 0;
    if (m_State == SIM_CLOCK_STATE_RUN)
    {
        elapsedTime = GetElapsedTimeUnlocked();
    }
    else
    {
        elapsedTime = m_ElapsedTimeWhenPaused;
    }

    if (pQpcTimeStamp)
    {
        *pQpcTimeStamp = m_QpcTimeStamp;
    }

    KeReleaseSpinLock(&m_Lock, irql);

    return elapsedTime;
}