1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18#define LOG_TAG "AAudioStreamParameters"
19#include <utils/Log.h>
20#include <system/audio.h>
21
22#include "AAudioStreamParameters.h"
23
24using namespace aaudio;
25
26// TODO These defines should be moved to a central place in audio.
27#define SAMPLES_PER_FRAME_MIN        1
28// TODO Remove 8 channel limitation.
29#define SAMPLES_PER_FRAME_MAX        FCC_8
30#define SAMPLE_RATE_HZ_MIN           8000
31// HDMI supports up to 32 channels at 1536000 Hz.
32#define SAMPLE_RATE_HZ_MAX           1600000
33
34AAudioStreamParameters::AAudioStreamParameters() {}
35AAudioStreamParameters::~AAudioStreamParameters() {}
36
37void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
38    mSamplesPerFrame = other.mSamplesPerFrame;
39    mSampleRate      = other.mSampleRate;
40    mDeviceId        = other.mDeviceId;
41    mSessionId       = other.mSessionId;
42    mSharingMode     = other.mSharingMode;
43    mAudioFormat     = other.mAudioFormat;
44    mDirection       = other.mDirection;
45    mBufferCapacity  = other.mBufferCapacity;
46    mUsage           = other.mUsage;
47    mContentType     = other.mContentType;
48    mInputPreset     = other.mInputPreset;
49}
50
51aaudio_result_t AAudioStreamParameters::validate() const {
52    if (mSamplesPerFrame != AAUDIO_UNSPECIFIED
53        && (mSamplesPerFrame < SAMPLES_PER_FRAME_MIN || mSamplesPerFrame > SAMPLES_PER_FRAME_MAX)) {
54        ALOGE("channelCount out of range = %d", mSamplesPerFrame);
55        return AAUDIO_ERROR_OUT_OF_RANGE;
56    }
57
58    if (mDeviceId < 0) {
59        ALOGE("deviceId out of range = %d", mDeviceId);
60        return AAUDIO_ERROR_OUT_OF_RANGE;
61    }
62
63    // All Session ID values are legal.
64    switch (mSessionId) {
65        case AAUDIO_SESSION_ID_NONE:
66        case AAUDIO_SESSION_ID_ALLOCATE:
67            break;
68        default:
69            break;
70    }
71
72    switch (mSharingMode) {
73        case AAUDIO_SHARING_MODE_EXCLUSIVE:
74        case AAUDIO_SHARING_MODE_SHARED:
75            break;
76        default:
77            ALOGE("illegal sharingMode = %d", mSharingMode);
78            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
79            // break;
80    }
81
82    switch (mAudioFormat) {
83        case AAUDIO_FORMAT_UNSPECIFIED:
84        case AAUDIO_FORMAT_PCM_I16:
85        case AAUDIO_FORMAT_PCM_FLOAT:
86            break; // valid
87        default:
88            ALOGE("audioFormat not valid = %d", mAudioFormat);
89            return AAUDIO_ERROR_INVALID_FORMAT;
90            // break;
91    }
92
93    if (mSampleRate != AAUDIO_UNSPECIFIED
94        && (mSampleRate < SAMPLE_RATE_HZ_MIN || mSampleRate > SAMPLE_RATE_HZ_MAX)) {
95        ALOGE("sampleRate out of range = %d", mSampleRate);
96        return AAUDIO_ERROR_INVALID_RATE;
97    }
98
99    if (mBufferCapacity < 0) {
100        ALOGE("bufferCapacity out of range = %d", mBufferCapacity);
101        return AAUDIO_ERROR_OUT_OF_RANGE;
102    }
103
104    switch (mDirection) {
105        case AAUDIO_DIRECTION_INPUT:
106        case AAUDIO_DIRECTION_OUTPUT:
107            break; // valid
108        default:
109            ALOGE("direction not valid = %d", mDirection);
110            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
111            // break;
112    }
113
114    switch (mUsage) {
115        case AAUDIO_UNSPECIFIED:
116        case AAUDIO_USAGE_MEDIA:
117        case AAUDIO_USAGE_VOICE_COMMUNICATION:
118        case AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
119        case AAUDIO_USAGE_ALARM:
120        case AAUDIO_USAGE_NOTIFICATION:
121        case AAUDIO_USAGE_NOTIFICATION_RINGTONE:
122        case AAUDIO_USAGE_NOTIFICATION_EVENT:
123        case AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
124        case AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
125        case AAUDIO_USAGE_ASSISTANCE_SONIFICATION:
126        case AAUDIO_USAGE_GAME:
127        case AAUDIO_USAGE_ASSISTANT:
128            break; // valid
129        default:
130            ALOGE("usage not valid = %d", mUsage);
131            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
132            // break;
133    }
134
135    switch (mContentType) {
136        case AAUDIO_UNSPECIFIED:
137        case AAUDIO_CONTENT_TYPE_MUSIC:
138        case AAUDIO_CONTENT_TYPE_MOVIE:
139        case AAUDIO_CONTENT_TYPE_SONIFICATION:
140        case AAUDIO_CONTENT_TYPE_SPEECH:
141            break; // valid
142        default:
143            ALOGE("content type not valid = %d", mContentType);
144            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
145            // break;
146    }
147
148    switch (mInputPreset) {
149        case AAUDIO_UNSPECIFIED:
150        case AAUDIO_INPUT_PRESET_GENERIC:
151        case AAUDIO_INPUT_PRESET_CAMCORDER:
152        case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
153        case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
154        case AAUDIO_INPUT_PRESET_UNPROCESSED:
155            break; // valid
156        default:
157            ALOGE("input preset not valid = %d", mInputPreset);
158            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
159            // break;
160    }
161
162    return AAUDIO_OK;
163}
164
165void AAudioStreamParameters::dump() const {
166    ALOGD("mDeviceId        = %6d", mDeviceId);
167    ALOGD("mSessionId       = %6d", mSessionId);
168    ALOGD("mSampleRate      = %6d", mSampleRate);
169    ALOGD("mSamplesPerFrame = %6d", mSamplesPerFrame);
170    ALOGD("mSharingMode     = %6d", (int)mSharingMode);
171    ALOGD("mAudioFormat     = %6d", (int)mAudioFormat);
172    ALOGD("mDirection       = %6d", mDirection);
173    ALOGD("mBufferCapacity  = %6d", mBufferCapacity);
174    ALOGD("mUsage           = %6d", mUsage);
175    ALOGD("mContentType     = %6d", mContentType);
176    ALOGD("mInputPreset     = %6d", mInputPreset);
177}
178