summaryrefslogtreecommitdiffstats
path: root/ppapi/shared_impl/ppb_audio_config_shared.cc
blob: 4b06d46d41cdb369ffa25f350bd30b480364bf89 (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
125
126
127
128
129
130
131
132
133
134
// Copyright (c) 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 "ppapi/shared_impl/ppb_audio_config_shared.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_instance_api.h"

namespace ppapi {

PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type,
                                               PP_Instance instance)
    : Resource(type, instance),
      sample_rate_(PP_AUDIOSAMPLERATE_NONE),
      sample_frame_count_(0) {
}

PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() {
}

PP_Resource PPB_AudioConfig_Shared::Create(
    ResourceObjectType type,
    PP_Instance instance,
    PP_AudioSampleRate sample_rate,
    uint32_t sample_frame_count) {
  scoped_refptr<PPB_AudioConfig_Shared> object(
      new PPB_AudioConfig_Shared(type, instance));
  if (!object->Init(sample_rate, sample_frame_count))
    return 0;
  return object->GetReference();
}

// static
uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_0(
    PP_AudioSampleRate sample_rate,
    uint32_t requested_sample_frame_count) {
  // Version 1.0: Don't actually query to get a value from the
  // hardware; instead return the input for in-range values.
  if (requested_sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    return PP_AUDIOMINSAMPLEFRAMECOUNT;
  if (requested_sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT)
    return PP_AUDIOMAXSAMPLEFRAMECOUNT;
  return requested_sample_frame_count;
}

// static
uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_1(
    PP_Instance instance,
    PP_AudioSampleRate sample_rate,
    uint32_t sample_frame_count) {
  // Version 1.1: Query the back-end hardware for sample rate and buffer size,
  // and recommend a best fit based on request.
  thunk::EnterInstance enter(instance);
  if (enter.failed())
    return 0;

  // Get the hardware config.
  PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>(
      enter.functions()->GetAudioHardwareOutputSampleRate(instance));
  uint32_t hardware_sample_frame_count =
      enter.functions()->GetAudioHardwareOutputBufferSize(instance);
  if (sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    sample_frame_count = PP_AUDIOMINSAMPLEFRAMECOUNT;

  // If client is using same sample rate as audio hardware, then recommend a
  // multiple of the audio hardware's sample frame count.
  if (hardware_sample_rate == sample_rate && hardware_sample_frame_count > 0) {
    // Round up input sample_frame_count to nearest multiple.
    uint32_t multiple = (sample_frame_count + hardware_sample_frame_count - 1) /
        hardware_sample_frame_count;
    uint32_t recommendation = hardware_sample_frame_count * multiple;
    if (recommendation > PP_AUDIOMAXSAMPLEFRAMECOUNT)
      recommendation = PP_AUDIOMAXSAMPLEFRAMECOUNT;
    return recommendation;
  }

  // Otherwise, recommend a conservative 50ms buffer based on sample rate.
  const uint32_t kDefault50msAt44100kHz = 2205;
  const uint32_t kDefault50msAt48000kHz = 2400;
  switch (sample_rate) {
    case PP_AUDIOSAMPLERATE_44100:
      return kDefault50msAt44100kHz;
    case PP_AUDIOSAMPLERATE_48000:
      return kDefault50msAt48000kHz;
    case PP_AUDIOSAMPLERATE_NONE:
      return 0;
  }
  // Unable to make a recommendation.
  return 0;
}

// static
PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate(
    PP_Instance instance) {
  thunk::EnterInstance enter(instance);
  if (enter.failed())
    return PP_AUDIOSAMPLERATE_NONE;
  PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>(
    enter.functions()->GetAudioHardwareOutputSampleRate(instance));
  return hardware_sample_rate;
}

thunk::PPB_AudioConfig_API* PPB_AudioConfig_Shared::AsPPB_AudioConfig_API() {
  return this;
}

PP_AudioSampleRate PPB_AudioConfig_Shared::GetSampleRate() {
  return sample_rate_;
}

uint32_t PPB_AudioConfig_Shared::GetSampleFrameCount() {
  return sample_frame_count_;
}

bool PPB_AudioConfig_Shared::Init(PP_AudioSampleRate sample_rate,
                                  uint32_t sample_frame_count) {
  // TODO(brettw): Currently we don't actually check what the hardware
  // supports, so just allow sample rates of the "guaranteed working" ones.
  if (sample_rate != PP_AUDIOSAMPLERATE_44100 &&
      sample_rate != PP_AUDIOSAMPLERATE_48000)
    return false;

  // TODO(brettw): Currently we don't actually query to get a value from the
  // hardware, so just validate the range.
  if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT ||
      sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    return false;

  sample_rate_ = sample_rate;
  sample_frame_count_ = sample_frame_count;
  return true;
}

}  // namespace ppapi