forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 2
/
bug564734-win32-drain.patch
149 lines (134 loc) · 4.54 KB
/
bug564734-win32-drain.patch
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
141
142
143
144
145
146
147
148
149
diff --git a/media/libsydneyaudio/src/sydney_audio_waveapi.c b/media/libsydneyaudio/src/sydney_audio_waveapi.c
--- a/media/libsydneyaudio/src/sydney_audio_waveapi.c
+++ b/media/libsydneyaudio/src/sydney_audio_waveapi.c
@@ -121,16 +121,17 @@ struct sa_stream {
};
/** Forward definitions of audio api specific functions */
int allocateBlocks(int size, int count, WAVEHDR** blocks);
int freeBlocks(WAVEHDR* blocks);
int openAudio(sa_stream_t *s);
int closeAudio(sa_stream_t * s);
+int writeBlock(sa_stream_t *s, WAVEHDR* current);
int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
int getSAErrorCode(int waveErrorCode);
void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg,
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
/** Normal way to open a PCM device */
int sa_stream_create_pcm(sa_stream_t **s,
@@ -320,20 +321,32 @@ int sa_stream_pause(sa_stream_t *s) {
status = waveOutPause(s->hWaveOut);
HANDLE_WAVE_ERROR(status, "resuming audio playback");
s->playing = 0;
return SA_SUCCESS;
}
+
/** Block until all audio has been played */
int sa_stream_drain(sa_stream_t *s) {
+ int status;
+ WAVEHDR* current;
+
ERROR_IF_NO_INIT(s);
-
+
+ current = &(s->waveBlocks[s->waveCurrentBlock]);
+ if (current->dwUser) {
+ /* We've got pending audio which hasn't been written, we must write it to
+ the hardware, else it will never be played. */
+ status = writeBlock(s, current);
+ HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+ }
+
if (!s->playing) {
return SA_ERROR_INVALID;
}
/* wait for all blocks to complete */
EnterCriticalSection(&(s->waveCriticalSection));
while(s->waveFreeBlockCount < BLOCK_COUNT) {
LeaveCriticalSection(&(s->waveCriticalSection));
@@ -502,16 +515,48 @@ int closeAudio(sa_stream_t * s) {
s->playing = 0;
DeleteCriticalSection(&(s->waveCriticalSection));
CloseHandle(s->callbackEvent);
return result;
}
+
+/**
+ * \brief - writes a WAVEHDR block of PCM audio samples to hardware.
+ * \param s - valid handle to opened sydney stream
+ * \param current - pointer to WAVEHDR storing audio samples to be played
+ * \return - completion status
+ */
+int writeBlock(sa_stream_t *s, WAVEHDR* current) {
+ int status;
+ ERROR_IF_NO_INIT(s);
+
+ current->dwBufferLength = current->dwUser;
+ /* write to audio device */
+ waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
+ status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
+ HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+
+ EnterCriticalSection(&(s->waveCriticalSection));
+ s->waveFreeBlockCount--;
+ LeaveCriticalSection(&(s->waveCriticalSection));
+
+ /*
+ * point to the next block
+ */
+ (s->waveCurrentBlock)++;
+ (s->waveCurrentBlock) %= BLOCK_COUNT;
+
+ s->playing = 1;
+
+ return SA_SUCCESS;
+}
+
/**
* \brief - writes PCM audio samples to audio device
* \param s - valid handle to opened sydney stream
* \param data - pointer to memory storing audio samples to be played
* \param nsamples - number of samples in the memory pointed by previous parameter
* \return - completion status
*/
int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {
@@ -536,40 +581,27 @@ int writeAudio(sa_stream_t *s, LPSTR dat
if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {
memcpy(current->lpData + current->dwUser, data, bytes);
current->dwUser += bytes;
break;
}
/* remain is even as BLOCK_SIZE and dwUser are even too */
- remain = BLOCK_SIZE - current->dwUser;
+ remain = BLOCK_SIZE - current->dwUser;
memcpy(current->lpData + current->dwUser, data, remain);
+ current->dwUser += remain;
bytes -= remain;
data += remain;
- current->dwBufferLength = BLOCK_SIZE;
- /* write to audio device */
- waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
- status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
+
+ status = writeBlock(s, current);
HANDLE_WAVE_ERROR(status, "writing audio to audio device");
-
- EnterCriticalSection(&(s->waveCriticalSection));
- s->waveFreeBlockCount--;
- LeaveCriticalSection(&(s->waveCriticalSection));
-
- /*
- * point to the next block
- */
- (s->waveCurrentBlock)++;
- (s->waveCurrentBlock) %= BLOCK_COUNT;
current = &(s->waveBlocks[s->waveCurrentBlock]);
current->dwUser = 0;
-
- s->playing = 1;
}
return SA_SUCCESS;
}
/**
* \brief - audio callback function called when next WAVE header is played by audio device
*/
void CALLBACK waveOutProc(