summaryrefslogtreecommitdiffstats
path: root/media/audio/ios/audio_manager_ios.mm
blob: cdae9adf664979549ea56f2b4f60b221b874a71b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/audio/ios/audio_manager_ios.h"

#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

#include "base/sys_info.h"
#include "media/audio/fake_audio_input_stream.h"
#include "media/audio/mac/audio_input_mac.h"
#include "media/base/limits.h"

namespace media {

enum { kMaxInputChannels = 2 };

// Initializes the audio session, returning a bool indicating whether
// initialization was successful. Should only be called once.
static bool InitAudioSessionInternal() {
  OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL);
  DCHECK(error != kAudioSessionAlreadyInitialized);
  AVAudioSession* audioSession = [AVAudioSession sharedInstance];
  BOOL result = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
                                    error:nil];
  DCHECK(result);
  return error == kAudioSessionNoError;
}

AudioManagerIOS::AudioManagerIOS() {
}

AudioManagerIOS::~AudioManagerIOS() {
  Shutdown();
}

bool AudioManagerIOS::HasAudioOutputDevices() {
  return false;
}

bool AudioManagerIOS::HasAudioInputDevices() {
  if (!InitAudioSession())
    return false;
  // Note that the |kAudioSessionProperty_AudioInputAvailable| property is a
  // 32-bit integer, not a boolean.
  UInt32 property_size;
  OSStatus error =
      AudioSessionGetPropertySize(kAudioSessionProperty_AudioInputAvailable,
                                  &property_size);
  if (error != kAudioSessionNoError)
    return false;
  UInt32 audio_input_is_available = false;
  DCHECK(property_size == sizeof(audio_input_is_available));
  error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable,
                                  &property_size,
                                  &audio_input_is_available);
  return error == kAudioSessionNoError ? audio_input_is_available : false;
}

AudioOutputStream* AudioManagerIOS::MakeAudioOutputStream(
    const AudioParameters& params) {
  NOTIMPLEMENTED();  // Only input is supported on iOS.
  return NULL;
}

AudioInputStream* AudioManagerIOS::MakeAudioInputStream(
    const AudioParameters& params, const std::string& device_id) {
  // Current line of iOS devices has only one audio input.
  // Ignore the device_id (unittest uses a test value in it).
  if (!params.IsValid() || (params.channels() > kMaxInputChannels))
    return NULL;

  if (params.format() == AudioParameters::AUDIO_FAKE)
    return FakeAudioInputStream::MakeFakeStream(this, params);
  else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR)
    return new PCMQueueInAudioInputStream(this, params);
  return NULL;
}

AudioOutputStream* AudioManagerIOS::MakeLinearOutputStream(
      const AudioParameters& params) {
  NOTIMPLEMENTED();  // Only input is supported on iOS.
  return NULL;
}

AudioOutputStream* AudioManagerIOS::MakeLowLatencyOutputStream(
      const AudioParameters& params) {
  NOTIMPLEMENTED();  // Only input is supported on iOS.
  return NULL;
}

AudioInputStream* AudioManagerIOS::MakeLinearInputStream(
      const AudioParameters& params, const std::string& device_id) {
  return MakeAudioInputStream(params, device_id);
}

AudioInputStream* AudioManagerIOS::MakeLowLatencyInputStream(
      const AudioParameters& params, const std::string& device_id) {
  NOTIMPLEMENTED();  // Only linear audio input is supported on iOS.
  return MakeAudioInputStream(params, device_id);
}

// Called by the stream when it has been released by calling Close().
void AudioManagerIOS::ReleaseOutputStream(AudioOutputStream* stream) {
  NOTIMPLEMENTED();  // Only input is supported on iOS.
}

// Called by the stream when it has been released by calling Close().
void AudioManagerIOS::ReleaseInputStream(AudioInputStream* stream) {
  delete stream;
}

bool AudioManagerIOS::InitAudioSession() {
  static const bool kSessionInitialized = InitAudioSessionInternal();
  return kSessionInitialized;
}

// static
AudioManager* CreateAudioManager() {
  return new AudioManagerIOS();
}

}  // namespace media