1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
6 #define MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "base/win/scoped_handle.h"
16 #include "media/audio/audio_io.h"
17 #include "media/audio/audio_parameters.h"
21 class AudioManagerWin
;
23 // Implements PCM audio output support for Windows using the WaveXXX API.
24 // While not as nice as the DirectSound-based API, it should work in all target
25 // operating systems regardless or DirectX version installed. It is known that
26 // in some machines WaveXXX based audio is better while in others DirectSound
29 // Important: the OnXXXX functions in AudioSourceCallback are called by more
30 // than one thread so it is important to have some form of synchronization if
31 // you are keeping state in it.
32 class PCMWaveOutAudioOutputStream
: public AudioOutputStream
{
34 // The ctor takes all the usual parameters, plus |manager| which is the the
35 // audio manager who is creating this object and |device_id| which is provided
36 // by the operating system.
37 PCMWaveOutAudioOutputStream(AudioManagerWin
* manager
,
38 const AudioParameters
& params
,
41 virtual ~PCMWaveOutAudioOutputStream();
43 // Implementation of AudioOutputStream.
46 virtual void Start(AudioSourceCallback
* callback
);
48 virtual void SetVolume(double volume
);
49 virtual void GetVolume(double* volume
);
51 // Sends a buffer to the audio driver for playback.
52 void QueueNextPacket(WAVEHDR
* buffer
);
56 PCMA_BRAND_NEW
, // Initial state.
57 PCMA_READY
, // Device obtained and ready to play.
58 PCMA_PLAYING
, // Playing audio.
59 PCMA_STOPPING
, // Audio is stopping, do not "feed" data to Windows.
60 PCMA_CLOSED
// Device has been released.
63 // Returns pointer to the n-th buffer.
64 inline WAVEHDR
* GetBuffer(int n
) const;
66 // Size of one buffer in bytes, rounded up if necessary.
67 inline size_t BufferSize() const;
69 // Windows calls us back asking for more data when buffer_event_ signalled.
70 // See MSDN for help on RegisterWaitForSingleObject() and waveOutOpen().
71 static void NTAPI
BufferCallback(PVOID lpParameter
, BOOLEAN timer_fired
);
73 // If windows reports an error this function handles it and passes it to
74 // the attached AudioSourceCallback::OnError().
75 void HandleError(MMRESULT error
);
77 // Allocates and prepares the memory that will be used for playback.
80 // Deallocates the memory allocated in SetupBuffers.
83 // Reader beware. Visual C has stronger guarantees on volatile vars than
84 // most people expect. In fact, it has release semantics on write and
85 // acquire semantics on reads. See the msdn documentation.
86 volatile State state_
;
88 // The audio manager that created this output stream. We notify it when
89 // we close so it can release its own resources.
90 AudioManagerWin
* manager_
;
92 // We use the callback mostly to periodically request more audio data.
93 AudioSourceCallback
* callback_
;
95 // The number of buffers of size |buffer_size_| each to use.
96 const int num_buffers_
;
98 // The size in bytes of each audio buffer, we usually have two of these.
101 // Volume level from 0 to 1.
104 // Channels from 0 to 8.
107 // Number of bytes yet to be played in the hardware buffer.
108 uint32 pending_bytes_
;
110 // The id assigned by the operating system to the selected wave output
111 // hardware device. Usually this is just -1 which means 'default device'.
114 // Windows native structure to encode the format parameters.
115 WAVEFORMATPCMEX format_
;
117 // Handle to the instance of the wave device.
120 // Handle to the buffer event.
121 base::win::ScopedHandle buffer_event_
;
123 // Handle returned by RegisterWaitForSingleObject().
124 HANDLE waiting_handle_
;
126 // Pointer to the allocated audio buffers, we allocate all buffers in one big
127 // chunk. This object owns them.
128 scoped_ptr
<char[]> buffers_
;
130 // Lock used to avoid the conflict when callbacks are called simultaneously.
133 // Container for retrieving data from AudioSourceCallback::OnMoreData().
134 scoped_ptr
<AudioBus
> audio_bus_
;
136 DISALLOW_COPY_AND_ASSIGN(PCMWaveOutAudioOutputStream
);
141 #endif // MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_