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_MAC_AUDIO_INPUT_MAC_H_
6#define MEDIA_AUDIO_MAC_AUDIO_INPUT_MAC_H_
7
8#include <AudioToolbox/AudioFormat.h>
9#include <AudioToolbox/AudioQueue.h>
10
11#include "base/cancelable_callback.h"
12#include "base/compiler_specific.h"
13#include "base/time/time.h"
14#include "media/audio/audio_io.h"
15#include "media/audio/audio_parameters.h"
16
17namespace media {
18
19class AudioBus;
20class AudioManagerMac;
21
22// Implementation of AudioInputStream for Mac OS X using the audio queue service
23// present in OS 10.5 and later. Design reflects PCMQueueOutAudioOutputStream.
24class PCMQueueInAudioInputStream : public AudioInputStream {
25 public:
26  // Parameters as per AudioManager::MakeAudioInputStream.
27  PCMQueueInAudioInputStream(AudioManagerMac* manager,
28                             const AudioParameters& params);
29  virtual ~PCMQueueInAudioInputStream();
30
31  // Implementation of AudioInputStream.
32  virtual bool Open() OVERRIDE;
33  virtual void Start(AudioInputCallback* callback) OVERRIDE;
34  virtual void Stop() OVERRIDE;
35  virtual void Close() OVERRIDE;
36  virtual double GetMaxVolume() OVERRIDE;
37  virtual void SetVolume(double volume) OVERRIDE;
38  virtual double GetVolume() OVERRIDE;
39  virtual void SetAutomaticGainControl(bool enabled) OVERRIDE;
40  virtual bool GetAutomaticGainControl() OVERRIDE;
41
42 private:
43  // Issue the OnError to |callback_|;
44  void HandleError(OSStatus err);
45
46  // Allocates and prepares the memory that will be used for recording.
47  bool SetupBuffers();
48
49  // Sends a buffer to the audio driver for recording.
50  OSStatus QueueNextBuffer(AudioQueueBufferRef audio_buffer);
51
52  // Callback from OS, delegates to non-static version below.
53  static void HandleInputBufferStatic(
54      void* data,
55      AudioQueueRef audio_queue,
56      AudioQueueBufferRef audio_buffer,
57      const AudioTimeStamp* start_time,
58      UInt32 num_packets,
59      const AudioStreamPacketDescription* desc);
60
61  // Handles callback from OS. Will be called on OS internal thread.
62  void HandleInputBuffer(AudioQueueRef audio_queue,
63                         AudioQueueBufferRef audio_buffer,
64                         const AudioTimeStamp* start_time,
65                         UInt32 num_packets,
66                         const AudioStreamPacketDescription* packet_desc);
67
68  static const int kNumberBuffers = 3;
69
70  // Manager that owns this stream, used for closing down.
71  AudioManagerMac* manager_;
72  // We use the callback mostly to periodically supply the recorded audio data.
73  AudioInputCallback* callback_;
74  // Structure that holds the stream format details such as bitrate.
75  AudioStreamBasicDescription format_;
76  // Handle to the OS audio queue object.
77  AudioQueueRef audio_queue_;
78  // Size of each of the buffers in |audio_buffers_|
79  uint32 buffer_size_bytes_;
80  // True iff Start() has been called successfully.
81  bool started_;
82  // Used to determine if we need to slow down |callback_| calls.
83  base::TimeTicks last_fill_;
84  // Used to defer Start() to workaround http://crbug.com/160920.
85  base::CancelableClosure deferred_start_cb_;
86
87  scoped_ptr<media::AudioBus> audio_bus_;
88
89  DISALLOW_COPY_AND_ASSIGN(PCMQueueInAudioInputStream);
90};
91
92}  // namespace media
93
94#endif  // MEDIA_AUDIO_MAC_AUDIO_INPUT_MAC_H_
95