summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/sdk/objc/components/audio/RTCAudioSessionConfiguration.m
blob: 71b0c0cb3a25cfdd23f8145c62a421109f7fd589 (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
/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#import "RTCAudioSessionConfiguration.h"
#import "RTCAudioSession.h"

#import "helpers/RTCDispatcher.h"
#import "helpers/UIDevice+RTCDevice.h"

// Try to use mono to save resources. Also avoids channel format conversion
// in the I/O audio unit. Initial tests have shown that it is possible to use
// mono natively for built-in microphones and for BT headsets but not for
// wired headsets. Wired headsets only support stereo as native channel format
// but it is a low cost operation to do a format conversion to mono in the
// audio unit. Hence, we will not hit a RTC_CHECK in
// VerifyAudioParametersForActiveAudioSession() for a mismatch between the
// preferred number of channels and the actual number of channels.
const int kRTCAudioSessionPreferredNumberOfChannels = 1;

// Preferred hardware sample rate (unit is in Hertz). The client sample rate
// will be set to this value as well to avoid resampling the the audio unit's
// format converter. Note that, some devices, e.g. BT headsets, only supports
// 8000Hz as native sample rate.
const double kRTCAudioSessionHighPerformanceSampleRate = 48000.0;

// Use a hardware I/O buffer size (unit is in seconds) that matches the 10ms
// size used by WebRTC. The exact actual size will differ between devices.
// Example: using 48kHz on iPhone 6 results in a native buffer size of
// ~10.6667ms or 512 audio frames per buffer. The FineAudioBuffer instance will
// take care of any buffering required to convert between native buffers and
// buffers used by WebRTC. It is beneficial for the performance if the native
// size is as an even multiple of 10ms as possible since it results in "clean"
// callback sequence without bursts of callbacks back to back.
const double kRTCAudioSessionHighPerformanceIOBufferDuration = 0.02;

static RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *gWebRTCConfiguration = nil;

@implementation RTC_OBJC_TYPE (RTCAudioSessionConfiguration)

@synthesize category = _category;
@synthesize categoryOptions = _categoryOptions;
@synthesize mode = _mode;
@synthesize sampleRate = _sampleRate;
@synthesize ioBufferDuration = _ioBufferDuration;
@synthesize inputNumberOfChannels = _inputNumberOfChannels;
@synthesize outputNumberOfChannels = _outputNumberOfChannels;

- (instancetype)init {
  if (self = [super init]) {
    // Use a category which supports simultaneous recording and playback.
    // By default, using this category implies that our app’s audio is
    // nonmixable, hence activating the session will interrupt any other
    // audio sessions which are also nonmixable.
    _category = AVAudioSessionCategoryPlayAndRecord;
    _categoryOptions = AVAudioSessionCategoryOptionAllowBluetooth;

    // Specify mode for two-way voice communication (e.g. VoIP).
    _mode = AVAudioSessionModeVoiceChat;

    // Use best sample rate and buffer duration if the CPU has more than one
    // core.
    _sampleRate = kRTCAudioSessionHighPerformanceSampleRate;
    _ioBufferDuration = kRTCAudioSessionHighPerformanceIOBufferDuration;

    // We try to use mono in both directions to save resources and format
    // conversions in the audio unit. Some devices does only support stereo;
    // e.g. wired headset on iPhone 6.
    // TODO(henrika): add support for stereo if needed.
    _inputNumberOfChannels = kRTCAudioSessionPreferredNumberOfChannels;
    _outputNumberOfChannels = kRTCAudioSessionPreferredNumberOfChannels;
  }
  return self;
}

+ (void)initialize {
  gWebRTCConfiguration = [[self alloc] init];
}

+ (instancetype)currentConfiguration {
  RTC_OBJC_TYPE(RTCAudioSession) *session = [RTC_OBJC_TYPE(RTCAudioSession) sharedInstance];
  RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *config =
      [[RTC_OBJC_TYPE(RTCAudioSessionConfiguration) alloc] init];
  config.category = session.category;
  config.categoryOptions = session.categoryOptions;
  config.mode = session.mode;
  config.sampleRate = session.sampleRate;
  config.ioBufferDuration = session.IOBufferDuration;
  config.inputNumberOfChannels = session.inputNumberOfChannels;
  config.outputNumberOfChannels = session.outputNumberOfChannels;
  return config;
}

+ (instancetype)webRTCConfiguration {
  @synchronized(self) {
    return (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)gWebRTCConfiguration;
  }
}

+ (void)setWebRTCConfiguration:(RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration {
  @synchronized(self) {
    gWebRTCConfiguration = configuration;
  }
}

@end