156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/* 256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project 356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License. 656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at 756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and 1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License. 1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */ 1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 1798cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#define LOG_TAG "APM::AudioGain" 1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0 1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define VERY_VERBOSE_LOGGING 2156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#ifdef VERY_VERBOSE_LOGGING 2256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define ALOGVV ALOGV 2356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#else 2456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define ALOGVV(a...) do { } while(0) 2556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#endif 2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2798cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h" 28ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/Log.h> 29ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/String8.h> 3056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 3156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#include <math.h> 3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 3356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 3456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 3556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviAudioGain::AudioGain(int index, bool useInChannelMask) 3656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mIndex = index; 3856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mUseInChannelMask = useInChannelMask; 3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi memset(&mGain, 0, sizeof(struct audio_gain)); 4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioGain::getDefaultConfig(struct audio_gain_config *config) 4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->index = mIndex; 4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->mode = mGain.mode; 4656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->channel_mask = mGain.channel_mask; 4756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 4856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->values[0] = mGain.default_value; 4956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 5056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi uint32_t numValues; 5156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mUseInChannelMask) { 5256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi numValues = audio_channel_count_from_in_mask(mGain.channel_mask); 5356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi numValues = audio_channel_count_from_out_mask(mGain.channel_mask); 5556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < numValues; i++) { 5756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->values[i] = mGain.default_value; 5856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 6056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 6156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi config->ramp_duration_ms = mGain.min_ramp_ms; 6256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 6356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 6456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 6556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioGain::checkConfig(const struct audio_gain_config *config) 6656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->mode & ~mGain.mode) != 0) { 6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return BAD_VALUE; 6956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { 7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->values[0] < mGain.min_value) || 7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi (config->values[0] > mGain.max_value)) { 7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return BAD_VALUE; 7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->channel_mask & ~mGain.channel_mask) != 0) { 7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return BAD_VALUE; 7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi uint32_t numValues; 8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mUseInChannelMask) { 8156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi numValues = audio_channel_count_from_in_mask(config->channel_mask); 8256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 8356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi numValues = audio_channel_count_from_out_mask(config->channel_mask); 8456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < numValues; i++) { 8656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->values[i] < mGain.min_value) || 8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi (config->values[i] > mGain.max_value)) { 8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return BAD_VALUE; 8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { 9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((config->ramp_duration_ms < mGain.min_ramp_ms) || 9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi (config->ramp_duration_ms > mGain.max_ramp_ms)) { 9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return BAD_VALUE; 9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioGain::dump(int fd, int spaces, int index) const 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1); 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode); 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask); 11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value); 11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value); 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value); 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value); 12056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms); 12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms); 12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; // namespace android 130