• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
6 #define MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
7 
8 #include <windows.h>
9 #include <mmsystem.h>
10 #include <mmreg.h>
11 
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"
18 
19 namespace media {
20 
21 class AudioManagerWin;
22 
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
27 // is better.
28 //
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 {
33  public:
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,
39                               int num_buffers,
40                               UINT device_id);
41   virtual ~PCMWaveOutAudioOutputStream();
42 
43   // Implementation of AudioOutputStream.
44   virtual bool Open();
45   virtual void Close();
46   virtual void Start(AudioSourceCallback* callback);
47   virtual void Stop();
48   virtual void SetVolume(double volume);
49   virtual void GetVolume(double* volume);
50 
51   // Sends a buffer to the audio driver for playback.
52   void QueueNextPacket(WAVEHDR* buffer);
53 
54  private:
55   enum State {
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.
61   };
62 
63   // Returns pointer to the n-th buffer.
64   inline WAVEHDR* GetBuffer(int n) const;
65 
66   // Size of one buffer in bytes, rounded up if necessary.
67   inline size_t BufferSize() const;
68 
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);
72 
73   // If windows reports an error this function handles it and passes it to
74   // the attached AudioSourceCallback::OnError().
75   void HandleError(MMRESULT error);
76 
77   // Allocates and prepares the memory that will be used for playback.
78   void SetupBuffers();
79 
80   // Deallocates the memory allocated in SetupBuffers.
81   void FreeBuffers();
82 
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_;
87 
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_;
91 
92   // We use the callback mostly to periodically request more audio data.
93   AudioSourceCallback* callback_;
94 
95   // The number of buffers of size |buffer_size_| each to use.
96   const int num_buffers_;
97 
98   // The size in bytes of each audio buffer, we usually have two of these.
99   uint32 buffer_size_;
100 
101   // Volume level from 0 to 1.
102   float volume_;
103 
104   // Channels from 0 to 8.
105   const int channels_;
106 
107   // Number of bytes yet to be played in the hardware buffer.
108   uint32 pending_bytes_;
109 
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'.
112   UINT device_id_;
113 
114   // Windows native structure to encode the format parameters.
115   WAVEFORMATPCMEX format_;
116 
117   // Handle to the instance of the wave device.
118   HWAVEOUT waveout_;
119 
120   // Handle to the buffer event.
121   base::win::ScopedHandle buffer_event_;
122 
123   // Handle returned by RegisterWaitForSingleObject().
124   HANDLE waiting_handle_;
125 
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_;
129 
130   // Lock used to avoid the conflict when callbacks are called simultaneously.
131   base::Lock lock_;
132 
133   // Container for retrieving data from AudioSourceCallback::OnMoreData().
134   scoped_ptr<AudioBus> audio_bus_;
135 
136   DISALLOW_COPY_AND_ASSIGN(PCMWaveOutAudioOutputStream);
137 };
138 
139 }  // namespace media
140 
141 #endif  // MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
142