Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / media / libsydneyaudio / bug564734-win32-drain.patch
blobaf702ed93b460d2c0ec0fcc172bf2ed2520ddfd9
1 diff --git a/media/libsydneyaudio/src/sydney_audio_waveapi.c b/media/libsydneyaudio/src/sydney_audio_waveapi.c
2 --- a/media/libsydneyaudio/src/sydney_audio_waveapi.c
3 +++ b/media/libsydneyaudio/src/sydney_audio_waveapi.c
4 @@ -121,16 +121,17 @@ struct sa_stream {
5 };
8 /** Forward definitions of audio api specific functions */
9 int allocateBlocks(int size, int count, WAVEHDR** blocks);
10 int freeBlocks(WAVEHDR* blocks);
11 int openAudio(sa_stream_t *s);
12 int closeAudio(sa_stream_t * s);
13 +int writeBlock(sa_stream_t *s, WAVEHDR* current);
14 int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
15 int getSAErrorCode(int waveErrorCode);
17 void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg,
18 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
20 /** Normal way to open a PCM device */
21 int sa_stream_create_pcm(sa_stream_t **s,
22 @@ -320,20 +321,32 @@ int sa_stream_pause(sa_stream_t *s) {
24 status = waveOutPause(s->hWaveOut);
25 HANDLE_WAVE_ERROR(status, "resuming audio playback");
27 s->playing = 0;
29 return SA_SUCCESS;
32 /** Block until all audio has been played */
33 int sa_stream_drain(sa_stream_t *s) {
34 + int status;
35 + WAVEHDR* current;
37 ERROR_IF_NO_INIT(s);
40 + current = &(s->waveBlocks[s->waveCurrentBlock]);
41 + if (current->dwUser) {
42 + /* We've got pending audio which hasn't been written, we must write it to
43 + the hardware, else it will never be played. */
44 + status = writeBlock(s, current);
45 + HANDLE_WAVE_ERROR(status, "writing audio to audio device");
46 + }
48 if (!s->playing) {
49 return SA_ERROR_INVALID;
52 /* wait for all blocks to complete */
53 EnterCriticalSection(&(s->waveCriticalSection));
54 while(s->waveFreeBlockCount < BLOCK_COUNT) {
55 LeaveCriticalSection(&(s->waveCriticalSection));
56 @@ -502,16 +515,48 @@ int closeAudio(sa_stream_t * s) {
58 s->playing = 0;
60 DeleteCriticalSection(&(s->waveCriticalSection));
61 CloseHandle(s->callbackEvent);
63 return result;
66 +/**
67 + * \brief - writes a WAVEHDR block of PCM audio samples to hardware.
68 + * \param s - valid handle to opened sydney stream
69 + * \param current - pointer to WAVEHDR storing audio samples to be played
70 + * \return - completion status
71 + */
72 +int writeBlock(sa_stream_t *s, WAVEHDR* current) {
73 + int status;
74 + ERROR_IF_NO_INIT(s);
76 + current->dwBufferLength = current->dwUser;
77 + /* write to audio device */
78 + waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
79 + status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
80 + HANDLE_WAVE_ERROR(status, "writing audio to audio device");
82 + EnterCriticalSection(&(s->waveCriticalSection));
83 + s->waveFreeBlockCount--;
84 + LeaveCriticalSection(&(s->waveCriticalSection));
86 + /*
87 + * point to the next block
88 + */
89 + (s->waveCurrentBlock)++;
90 + (s->waveCurrentBlock) %= BLOCK_COUNT;
92 + s->playing = 1;
94 + return SA_SUCCESS;
97 /**
98 * \brief - writes PCM audio samples to audio device
99 * \param s - valid handle to opened sydney stream
100 * \param data - pointer to memory storing audio samples to be played
101 * \param nsamples - number of samples in the memory pointed by previous parameter
102 * \return - completion status
104 int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {
105 @@ -536,40 +581,27 @@ int writeAudio(sa_stream_t *s, LPSTR dat
107 if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {
108 memcpy(current->lpData + current->dwUser, data, bytes);
109 current->dwUser += bytes;
110 break;
113 /* remain is even as BLOCK_SIZE and dwUser are even too */
114 - remain = BLOCK_SIZE - current->dwUser;
115 + remain = BLOCK_SIZE - current->dwUser;
116 memcpy(current->lpData + current->dwUser, data, remain);
117 + current->dwUser += remain;
118 bytes -= remain;
119 data += remain;
120 - current->dwBufferLength = BLOCK_SIZE;
121 - /* write to audio device */
122 - waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
123 - status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
125 + status = writeBlock(s, current);
126 HANDLE_WAVE_ERROR(status, "writing audio to audio device");
128 - EnterCriticalSection(&(s->waveCriticalSection));
129 - s->waveFreeBlockCount--;
130 - LeaveCriticalSection(&(s->waveCriticalSection));
132 - /*
133 - * point to the next block
134 - */
135 - (s->waveCurrentBlock)++;
136 - (s->waveCurrentBlock) %= BLOCK_COUNT;
138 current = &(s->waveBlocks[s->waveCurrentBlock]);
139 current->dwUser = 0;
141 - s->playing = 1;
143 return SA_SUCCESS;
147 * \brief - audio callback function called when next WAVE header is played by audio device
149 void CALLBACK waveOutProc(