| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ANDROID_MICROPHONE_INFO_H |
| #define ANDROID_MICROPHONE_INFO_H |
| |
| #include <binder/Parcel.h> |
| #include <binder/Parcelable.h> |
| #include <system/audio.h> |
| #include <utils/String16.h> |
| #include <utils/Vector.h> |
| |
| namespace android { |
| namespace media { |
| |
| #define RETURN_IF_FAILED(calledOnce) \ |
| { \ |
| status_t returnStatus = calledOnce; \ |
| if (returnStatus) { \ |
| ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ |
| return returnStatus; \ |
| } \ |
| } |
| |
| class MicrophoneInfo : public Parcelable { |
| public: |
| MicrophoneInfo() = default; |
| MicrophoneInfo(const MicrophoneInfo& microphoneInfo) = default; |
| MicrophoneInfo(audio_microphone_characteristic_t& characteristic) { |
| mDeviceId = String16(&characteristic.device_id[0]); |
| mPortId = characteristic.id; |
| mType = characteristic.device; |
| mAddress = String16(&characteristic.address[0]); |
| mDeviceLocation = characteristic.location; |
| mDeviceGroup = characteristic.group; |
| mIndexInTheGroup = characteristic.index_in_the_group; |
| mGeometricLocation.push_back(characteristic.geometric_location.x); |
| mGeometricLocation.push_back(characteristic.geometric_location.y); |
| mGeometricLocation.push_back(characteristic.geometric_location.z); |
| mOrientation.push_back(characteristic.orientation.x); |
| mOrientation.push_back(characteristic.orientation.y); |
| mOrientation.push_back(characteristic.orientation.z); |
| Vector<float> frequencies; |
| Vector<float> responses; |
| for (size_t i = 0; i < characteristic.num_frequency_responses; i++) { |
| frequencies.push_back(characteristic.frequency_responses[0][i]); |
| responses.push_back(characteristic.frequency_responses[1][i]); |
| } |
| mFrequencyResponses.push_back(frequencies); |
| mFrequencyResponses.push_back(responses); |
| for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) { |
| mChannelMapping.push_back(characteristic.channel_mapping[i]); |
| } |
| mSensitivity = characteristic.sensitivity; |
| mMaxSpl = characteristic.max_spl; |
| mMinSpl = characteristic.min_spl; |
| mDirectionality = characteristic.directionality; |
| } |
| |
| virtual ~MicrophoneInfo() = default; |
| |
| virtual status_t writeToParcel(Parcel* parcel) const { |
| RETURN_IF_FAILED(parcel->writeString16(mDeviceId)); |
| RETURN_IF_FAILED(parcel->writeInt32(mPortId)); |
| RETURN_IF_FAILED(parcel->writeUint32(mType)); |
| RETURN_IF_FAILED(parcel->writeString16(mAddress)); |
| RETURN_IF_FAILED(parcel->writeInt32(mDeviceLocation)); |
| RETURN_IF_FAILED(parcel->writeInt32(mDeviceGroup)); |
| RETURN_IF_FAILED(parcel->writeInt32(mIndexInTheGroup)); |
| RETURN_IF_FAILED(writeFloatVector(parcel, mGeometricLocation)); |
| RETURN_IF_FAILED(writeFloatVector(parcel, mOrientation)); |
| if (mFrequencyResponses.size() != 2) { |
| return BAD_VALUE; |
| } |
| for (size_t i = 0; i < mFrequencyResponses.size(); i++) { |
| RETURN_IF_FAILED(parcel->writeInt32(mFrequencyResponses[i].size())); |
| RETURN_IF_FAILED(writeFloatVector(parcel, mFrequencyResponses[i])); |
| } |
| std::vector<int> channelMapping; |
| for (size_t i = 0; i < mChannelMapping.size(); ++i) { |
| channelMapping.push_back(mChannelMapping[i]); |
| } |
| RETURN_IF_FAILED(parcel->writeInt32Vector(channelMapping)); |
| RETURN_IF_FAILED(parcel->writeFloat(mSensitivity)); |
| RETURN_IF_FAILED(parcel->writeFloat(mMaxSpl)); |
| RETURN_IF_FAILED(parcel->writeFloat(mMinSpl)); |
| RETURN_IF_FAILED(parcel->writeInt32(mDirectionality)); |
| return OK; |
| } |
| |
| virtual status_t readFromParcel(const Parcel* parcel) { |
| RETURN_IF_FAILED(parcel->readString16(&mDeviceId)); |
| RETURN_IF_FAILED(parcel->readInt32(&mPortId)); |
| RETURN_IF_FAILED(parcel->readUint32(&mType)); |
| RETURN_IF_FAILED(parcel->readString16(&mAddress)); |
| RETURN_IF_FAILED(parcel->readInt32(&mDeviceLocation)); |
| RETURN_IF_FAILED(parcel->readInt32(&mDeviceGroup)); |
| RETURN_IF_FAILED(parcel->readInt32(&mIndexInTheGroup)); |
| RETURN_IF_FAILED(readFloatVector(parcel, &mGeometricLocation, 3)); |
| RETURN_IF_FAILED(readFloatVector(parcel, &mOrientation, 3)); |
| int32_t frequenciesNum; |
| RETURN_IF_FAILED(parcel->readInt32(&frequenciesNum)); |
| Vector<float> frequencies; |
| RETURN_IF_FAILED(readFloatVector(parcel, &frequencies, frequenciesNum)); |
| int32_t responsesNum; |
| RETURN_IF_FAILED(parcel->readInt32(&responsesNum)); |
| Vector<float> responses; |
| RETURN_IF_FAILED(readFloatVector(parcel, &responses, responsesNum)); |
| if (frequencies.size() != responses.size()) { |
| return BAD_VALUE; |
| } |
| mFrequencyResponses.push_back(frequencies); |
| mFrequencyResponses.push_back(responses); |
| std::vector<int> channelMapping; |
| status_t result = parcel->readInt32Vector(&channelMapping); |
| if (result != OK) { |
| return result; |
| } |
| if (channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) { |
| return BAD_VALUE; |
| } |
| for (size_t i = 0; i < channelMapping.size(); i++) { |
| mChannelMapping.push_back(channelMapping[i]); |
| } |
| RETURN_IF_FAILED(parcel->readFloat(&mSensitivity)); |
| RETURN_IF_FAILED(parcel->readFloat(&mMaxSpl)); |
| RETURN_IF_FAILED(parcel->readFloat(&mMinSpl)); |
| RETURN_IF_FAILED(parcel->readInt32(&mDirectionality)); |
| return OK; |
| } |
| |
| String16 getDeviceId() const { |
| return mDeviceId; |
| } |
| |
| int getPortId() const { |
| return mPortId; |
| } |
| |
| unsigned int getType() const { |
| return mType; |
| } |
| |
| String16 getAddress() const { |
| return mAddress; |
| } |
| |
| int getDeviceLocation() const { |
| return mDeviceLocation; |
| } |
| |
| int getDeviceGroup() const { |
| return mDeviceGroup; |
| } |
| |
| int getIndexInTheGroup() const { |
| return mIndexInTheGroup; |
| } |
| |
| const Vector<float>& getGeometricLocation() const { |
| return mGeometricLocation; |
| } |
| |
| const Vector<float>& getOrientation() const { |
| return mOrientation; |
| } |
| |
| const Vector<Vector<float>>& getFrequencyResponses() const { |
| return mFrequencyResponses; |
| } |
| |
| const Vector<int>& getChannelMapping() const { |
| return mChannelMapping; |
| } |
| |
| float getSensitivity() const { |
| return mSensitivity; |
| } |
| |
| float getMaxSpl() const { |
| return mMaxSpl; |
| } |
| |
| float getMinSpl() const { |
| return mMinSpl; |
| } |
| |
| int getDirectionality() const { |
| return mDirectionality; |
| } |
| |
| private: |
| status_t readFloatVector( |
| const Parcel* parcel, Vector<float> *vectorPtr, size_t defaultLength) { |
| std::unique_ptr<std::vector<float>> v; |
| status_t result = parcel->readFloatVector(&v); |
| if (result != OK) return result; |
| vectorPtr->clear(); |
| if (v.get() != nullptr) { |
| for (const auto& iter : *v) { |
| vectorPtr->push_back(iter); |
| } |
| } else { |
| vectorPtr->resize(defaultLength); |
| } |
| return OK; |
| } |
| status_t writeFloatVector(Parcel* parcel, const Vector<float>& vector) const { |
| std::vector<float> v; |
| for (size_t i = 0; i < vector.size(); i++) { |
| v.push_back(vector[i]); |
| } |
| return parcel->writeFloatVector(v); |
| } |
| |
| String16 mDeviceId; |
| int32_t mPortId; |
| uint32_t mType; |
| String16 mAddress; |
| int32_t mDeviceLocation; |
| int32_t mDeviceGroup; |
| int32_t mIndexInTheGroup; |
| Vector<float> mGeometricLocation; |
| Vector<float> mOrientation; |
| Vector<Vector<float>> mFrequencyResponses; |
| Vector<int> mChannelMapping; |
| float mSensitivity; |
| float mMaxSpl; |
| float mMinSpl; |
| int32_t mDirectionality; |
| }; |
| |
| } // namespace media |
| } // namespace android |
| |
| #endif |