1dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie/*
2dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * Copyright (C) 2015 The Android Open Source Project
3dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie *
4dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * Licensed under the Apache License, Version 2.0 (the "License");
5dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * you may not use this file except in compliance with the License.
6dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * You may obtain a copy of the License at
7dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie *
8dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie *      http://www.apache.org/licenses/LICENSE-2.0
9dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie *
10dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * Unless required by applicable law or agreed to in writing, software
11dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * distributed under the License is distributed on an "AS IS" BASIS,
12dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * See the License for the specific language governing permissions and
14dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie * limitations under the License.
15dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie */
16dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
17dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#define LOG_TAG "APM::Volumes"
18dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie//#define LOG_NDEBUG 0
19dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
20dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie//#define VERY_VERBOSE_LOGGING
21dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#ifdef VERY_VERBOSE_LOGGING
22dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#define ALOGVV ALOGV
23dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#else
24dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#define ALOGVV(a...) do { } while(0)
25dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#endif
26dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
27dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#include "StreamDescriptor.h"
28d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include "Gains.h"
290631aee95c5a98fb2dc0a45f093f9bd0cfbe463fEric Laurent#include "policy.h"
30dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#include <utils/Log.h>
31dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie#include <utils/String8.h>
32dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
33dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffienamespace android {
34dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
35dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie// --- StreamDescriptor class implementation
36dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
37dfd7409c1b708f6c429aa43722ca8493a91d8df0François GaffieStreamDescriptor::StreamDescriptor()
38dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
39dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
405664139e0ae16bb180a8eaae917f35f7c99d2a0aRalph Nathan    // Initialize the current stream's index to mIndexMax so volume isn't 0 in
415664139e0ae16bb180a8eaae917f35f7c99d2a0aRalph Nathan    // cases where the Java layer doesn't call into the audio policy service to
425664139e0ae16bb180a8eaae917f35f7c99d2a0aRalph Nathan    // set the default volume.
435a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, mIndexMax);
44dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
45dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
46dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffieint StreamDescriptor::getVolumeIndex(audio_devices_t device) const
47dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
48dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    device = Volume::getDeviceForVolume(device);
495a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
50dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    if (mIndexCur.indexOfKey(device) < 0) {
515a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
52dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    }
53dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return mIndexCur.valueFor(device);
54dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
55dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
56dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptor::clearCurrentVolumeIndex()
57dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
58dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    mIndexCur.clear();
59dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
60dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
61dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptor::addCurrentVolumeIndex(audio_devices_t device, int index)
62dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
63dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    mIndexCur.add(device, index);
64dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
65dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
66dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptor::setVolumeIndexMin(int volIndexMin)
67dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
68dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    mIndexMin = volIndexMin;
69dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
70dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
71dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptor::setVolumeIndexMax(int volIndexMax)
72dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
73dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    mIndexMax = volIndexMax;
74dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
75dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
76d0609ad390ff8bb1cafebdf363bf1d15e63b949fFrançois Gaffievoid StreamDescriptor::setVolumeCurvePoint(device_category deviceCategory,
77dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie                                           const VolumeCurvePoint *point)
78dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
79dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    mVolumeCurve[deviceCategory] = point;
80dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
81dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
82dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptor::dump(int fd) const
83dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
84dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    const size_t SIZE = 256;
85dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    char buffer[SIZE];
86dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    String8 result;
87dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
88dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
89dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
90dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    result.append(buffer);
91dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    for (size_t i = 0; i < mIndexCur.size(); i++) {
92dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        snprintf(buffer, SIZE, "%04x : %02d, ",
93dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie                 mIndexCur.keyAt(i),
94dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie                 mIndexCur.valueAt(i));
95dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        result.append(buffer);
96dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    }
97dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    result.append("\n");
98dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
99dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    write(fd, result.string(), result.size());
100dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
101dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
102dfd7409c1b708f6c429aa43722ca8493a91d8df0François GaffieStreamDescriptorCollection::StreamDescriptorCollection()
103dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
104dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    for (size_t stream = 0 ; stream < AUDIO_STREAM_CNT; stream++) {
105dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        add(static_cast<audio_stream_type_t>(stream), StreamDescriptor());
106dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    }
107dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
108dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
109dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffiebool StreamDescriptorCollection::canBeMuted(audio_stream_type_t stream)
110dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
111dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return valueAt(stream).canBeMuted();
112dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
113dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
114dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptorCollection::clearCurrentVolumeIndex(audio_stream_type_t stream)
115dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
116dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    editValueAt(stream).clearCurrentVolumeIndex();
117dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
118dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
119dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptorCollection::addCurrentVolumeIndex(audio_stream_type_t stream,
120dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie                                                       audio_devices_t device, int index)
121dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
122dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    editValueAt(stream).addCurrentVolumeIndex(device, index);
123dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
124dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
125dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptorCollection::setVolumeCurvePoint(audio_stream_type_t stream,
126d0609ad390ff8bb1cafebdf363bf1d15e63b949fFrançois Gaffie                                                     device_category deviceCategory,
127dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie                                                     const VolumeCurvePoint *point)
128dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
129dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    editValueAt(stream).setVolumeCurvePoint(deviceCategory, point);
130dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
131dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
132dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffieconst VolumeCurvePoint *StreamDescriptorCollection::getVolumeCurvePoint(audio_stream_type_t stream,
133d0609ad390ff8bb1cafebdf363bf1d15e63b949fFrançois Gaffie                                                                        device_category deviceCategory) const
134dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
135dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return valueAt(stream).getVolumeCurvePoint(deviceCategory);
136dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
137dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
138dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptorCollection::setVolumeIndexMin(audio_stream_type_t stream,int volIndexMin)
139dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
140dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return editValueAt(stream).setVolumeIndexMin(volIndexMin);
141dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
142dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
143dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffievoid StreamDescriptorCollection::setVolumeIndexMax(audio_stream_type_t stream,int volIndexMax)
144dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
145dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return editValueAt(stream).setVolumeIndexMax(volIndexMax);
146dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
147dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
148d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffiefloat StreamDescriptorCollection::volIndexToDb(audio_stream_type_t stream, device_category category,
149d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                               int indexInUi) const
150d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{
151d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    const StreamDescriptor &streamDesc = valueAt(stream);
152d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    return Gains::volIndexToDb(streamDesc.getVolumeCurvePoint(category),
153d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                               streamDesc.getVolumeIndexMin(), streamDesc.getVolumeIndexMax(),
154d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                               indexInUi);
155d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}
156d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
157d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffiestatus_t StreamDescriptorCollection::initStreamVolume(audio_stream_type_t stream,
158d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                                      int indexMin, int indexMax)
159d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{
160d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
161d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (indexMin < 0 || indexMin >= indexMax) {
162d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d",
163d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie              stream , indexMin, indexMax);
164d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        return BAD_VALUE;
165d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
166d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    setVolumeIndexMin(stream, indexMin);
167d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    setVolumeIndexMax(stream, indexMax);
168d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    return NO_ERROR;
169d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}
170d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
171d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffievoid StreamDescriptorCollection::initializeVolumeCurves(bool isSpeakerDrcEnabled)
172d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{
173d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
174d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
175d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
176d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                static_cast<device_category>(j),
177d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                Gains::sVolumeProfiles[i][j]);
178d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        }
179d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
180d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
181d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Check availability of DRC on speaker path: if available, override some of the speaker curves
182d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (isSpeakerDrcEnabled) {
183d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, DEVICE_CATEGORY_SPEAKER,
184d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sDefaultSystemVolumeCurveDrc);
185d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_RING, DEVICE_CATEGORY_SPEAKER,
186d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sSpeakerSonificationVolumeCurveDrc);
187d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_ALARM, DEVICE_CATEGORY_SPEAKER,
188d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sSpeakerSonificationVolumeCurveDrc);
189d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, DEVICE_CATEGORY_SPEAKER,
190d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sSpeakerSonificationVolumeCurveDrc);
191d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_MUSIC, DEVICE_CATEGORY_SPEAKER,
192d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sSpeakerMediaVolumeCurveDrc);
193d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, DEVICE_CATEGORY_SPEAKER,
194d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sSpeakerMediaVolumeCurveDrc);
195d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
196d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}
197d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
198d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffievoid StreamDescriptorCollection::switchVolumeCurve(audio_stream_type_t streamSrc,
199d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                                   audio_stream_type_t streamDst)
200d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{
201d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
202d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        setVolumeCurvePoint(streamDst, static_cast<device_category>(j),
203d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                            Gains::sVolumeProfiles[streamSrc][j]);
204d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
205d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}
206d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
207dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffiestatus_t StreamDescriptorCollection::dump(int fd) const
208dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie{
209dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    const size_t SIZE = 256;
210dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    char buffer[SIZE];
211dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
212dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    snprintf(buffer, SIZE, "\nStreams dump:\n");
213dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    write(fd, buffer, strlen(buffer));
214dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    snprintf(buffer, SIZE,
215dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
216dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    write(fd, buffer, strlen(buffer));
217dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    for (size_t i = 0; i < size(); i++) {
218dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        snprintf(buffer, SIZE, " %02zu      ", i);
219dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        write(fd, buffer, strlen(buffer));
220dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie        valueAt(i).dump(fd);
221dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    }
222dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
223dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    return NO_ERROR;
224dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}
225dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie
226dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie}; // namespace android
227