OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/audio/audio_io.h" | 5 #include "media/audio/audio_io.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <mmsystem.h> | 8 #include <mmsystem.h> |
9 | 9 |
10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "media/audio/fake_audio_output_stream.h" | 12 #include "media/audio/fake_audio_output_stream.h" |
13 #include "media/audio/win/audio_manager_win.h" | 13 #include "media/audio/win/audio_manager_win.h" |
| 14 #include "media/audio/win/wavein_input_win.h" |
14 #include "media/audio/win/waveout_output_win.h" | 15 #include "media/audio/win/waveout_output_win.h" |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 // The next 3 constants are some sensible limits to prevent integer overflow | 19 // The next 3 constants are some sensible limits to prevent integer overflow |
19 // at this layer. | 20 // at this layer. |
20 // Up to 6 channels can be passed to the driver. | 21 // Up to 6 channels can be passed to the driver. |
21 // This should work, given the right drivers, but graceful error handling is | 22 // This should work, given the right drivers, but graceful error handling is |
22 // needed. | 23 // needed. |
23 // In theory 7.1 could also be supported, but it has not been tested. | 24 // In theory 7.1 could also be supported, but it has not been tested. |
24 // The 192 Khz constant is the frequency of quicktime lossless audio codec. | 25 // The 192 Khz constant is the frequency of quicktime lossless audio codec. |
25 // MP4 is limited to 96 Khz, and mp3 is limited to 48 Khz. | 26 // MP4 is limited to 96 Khz, and mp3 is limited to 48 Khz. |
26 // OGG vorbis was initially limited to 96 Khz, but recent tools are unlimited. | 27 // OGG vorbis was initially limited to 96 Khz, but recent tools are unlimited. |
27 // 192 Khz is also the limit on most PC audio hardware. The minimum is 100 Hz. | 28 // 192 Khz is also the limit on most PC audio hardware. The minimum is 100 Hz. |
28 // Humans range is 20 to 20000 Hz. Below 20 can be felt (woofer). | 29 // Humans range is 20 to 20000 Hz. Below 20 can be felt (woofer). |
29 | 30 |
30 const int kMaxChannels = 6; | 31 const int kMaxChannels = 6; |
31 const int kMaxSampleRate = 192000; | 32 const int kMaxSampleRate = 192000; |
32 const int kMaxBitsPerSample = 64; | 33 const int kMaxBitsPerSample = 64; |
33 | 34 |
| 35 const int kMaxInputChannels = 2; |
| 36 const int kMaxSamplesPerPacket = kMaxSampleRate; |
| 37 // We use 3 buffers for recording audio so that if a recording callback takes |
| 38 // some time to return we won't lose audio. More buffers while recording are |
| 39 // ok because they don't introduce any delay in recording, unlike in playback |
| 40 // where you first need to fill in that number of buffers before starting to |
| 41 // play. |
| 42 const int kNumInputBuffers = 3; |
| 43 |
34 AudioManagerWin* g_audio_manager = NULL; | 44 AudioManagerWin* g_audio_manager = NULL; |
35 | 45 |
36 } // namespace. | 46 } // namespace. |
37 | 47 |
38 bool AudioManagerWin::HasAudioOutputDevices() { | 48 bool AudioManagerWin::HasAudioOutputDevices() { |
39 return (::waveOutGetNumDevs() != 0); | 49 return (::waveOutGetNumDevs() != 0); |
40 } | 50 } |
41 | 51 |
| 52 bool AudioManagerWin::HasAudioInputDevices() { |
| 53 return (::waveInGetNumDevs() != 0); |
| 54 } |
| 55 |
42 // Factory for the implementations of AudioOutputStream. Two implementations | 56 // Factory for the implementations of AudioOutputStream. Two implementations |
43 // should suffice most windows user's needs. | 57 // should suffice most windows user's needs. |
44 // - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress) | 58 // - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress) |
45 // - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work). | 59 // - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work). |
46 AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( | 60 AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( |
47 Format format, | 61 Format format, |
48 int channels, | 62 int channels, |
49 int sample_rate, | 63 int sample_rate, |
50 char bits_per_sample) { | 64 char bits_per_sample) { |
51 if ((channels > kMaxChannels) || (channels <= 0) || | 65 if ((channels > kMaxChannels) || (channels <= 0) || |
52 (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || | 66 (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || |
53 (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0)) | 67 (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0)) |
54 return NULL; | 68 return NULL; |
55 | 69 |
56 if (format == AUDIO_MOCK) { | 70 if (format == AUDIO_MOCK) { |
57 return FakeAudioOutputStream::MakeFakeStream(); | 71 return FakeAudioOutputStream::MakeFakeStream(); |
58 } else if (format == AUDIO_PCM_LINEAR) { | 72 } else if (format == AUDIO_PCM_LINEAR) { |
59 return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 3, | 73 return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 3, |
60 bits_per_sample, WAVE_MAPPER); | 74 bits_per_sample, WAVE_MAPPER); |
61 } else if (format == AUDIO_PCM_LOW_LATENCY) { | 75 } else if (format == AUDIO_PCM_LOW_LATENCY) { |
62 // TODO(cpu): waveout cannot hit 20ms latency. Use other method. | 76 // TODO(cpu): waveout cannot hit 20ms latency. Use other method. |
63 return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 2, | 77 return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 2, |
64 bits_per_sample, WAVE_MAPPER); | 78 bits_per_sample, WAVE_MAPPER); |
65 } | 79 } |
66 return NULL; | 80 return NULL; |
67 } | 81 } |
68 | 82 |
| 83 // Factory for the implementations of AudioInputStream. |
| 84 AudioInputStream* AudioManagerWin::MakeAudioInputStream( |
| 85 Format format, |
| 86 int channels, |
| 87 int sample_rate, |
| 88 char bits_per_sample, |
| 89 uint32 samples_per_packet) { |
| 90 if ((channels > kMaxInputChannels) || (channels <= 0) || |
| 91 (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || |
| 92 (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0) || |
| 93 (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) |
| 94 return NULL; |
| 95 |
| 96 if (format == AUDIO_MOCK) { |
| 97 // TODO(satish): Add mock audio input stream. |
| 98 } else if (format == AUDIO_PCM_LINEAR) { |
| 99 return new PCMWaveInAudioInputStream(this, channels, sample_rate, |
| 100 kNumInputBuffers, bits_per_sample, |
| 101 samples_per_packet, WAVE_MAPPER); |
| 102 } |
| 103 return NULL; |
| 104 } |
| 105 |
69 void AudioManagerWin::ReleaseOutputStream(PCMWaveOutAudioOutputStream* stream) { | 106 void AudioManagerWin::ReleaseOutputStream(PCMWaveOutAudioOutputStream* stream) { |
70 if (stream) | 107 if (stream) |
71 delete stream; | 108 delete stream; |
72 } | 109 } |
73 | 110 |
| 111 void AudioManagerWin::ReleaseInputStream(PCMWaveInAudioInputStream* stream) { |
| 112 if (stream) |
| 113 delete stream; |
| 114 } |
| 115 |
74 void AudioManagerWin::MuteAll() { | 116 void AudioManagerWin::MuteAll() { |
75 } | 117 } |
76 | 118 |
77 void AudioManagerWin::UnMuteAll() { | 119 void AudioManagerWin::UnMuteAll() { |
78 } | 120 } |
79 | 121 |
80 AudioManagerWin::~AudioManagerWin() { | 122 AudioManagerWin::~AudioManagerWin() { |
81 } | 123 } |
82 | 124 |
83 void DestroyAudioManagerWin(void* param) { | 125 void DestroyAudioManagerWin(void* param) { |
84 delete g_audio_manager; | 126 delete g_audio_manager; |
85 g_audio_manager = NULL; | 127 g_audio_manager = NULL; |
86 } | 128 } |
87 | 129 |
88 AudioManager* AudioManager::GetAudioManager() { | 130 AudioManager* AudioManager::GetAudioManager() { |
89 if (!g_audio_manager) { | 131 if (!g_audio_manager) { |
90 g_audio_manager = new AudioManagerWin(); | 132 g_audio_manager = new AudioManagerWin(); |
91 base::AtExitManager::RegisterCallback(&DestroyAudioManagerWin, NULL); | 133 base::AtExitManager::RegisterCallback(&DestroyAudioManagerWin, NULL); |
92 } | 134 } |
93 return g_audio_manager; | 135 return g_audio_manager; |
94 } | 136 } |
OLD | NEW |