1 /* 2 * Copyright 2018 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "audio_utils_format_tests" 19 #include <log/log.h> 20 21 #include <audio_utils/format.h> 22 #include <gtest/gtest.h> 23 24 /** returns true if the format is a common source or destination format. 25 memcpy_by_audio_format() allows interchange between any PCM format and the 26 "common" PCM 16 bit and PCM float formats. */ 27 static bool is_common_format(audio_format_t format) { 28 return format == AUDIO_FORMAT_PCM_16_BIT || format == AUDIO_FORMAT_PCM_FLOAT; 29 } 30 31 // Initialize PCM 16 bit ramp for basic data sanity check (generated from PCM 8 bit data). 32 // TODO: consider creating fillPseudoRandomValue(). 33 template<size_t size> 34 static void fillRamp(int16_t(&buffer)[size]) 35 { 36 // Create PCM 16 bit data based on PCM 8 bit format because PCM 8 bit is convertible 37 // to all other audio formats without loss; hence, round trip conversion preserves equality. 38 uint8_t bytes[size]; 39 for (size_t i = 0; i < size; ++i) { 40 bytes[i] = i; 41 } 42 // convert to PCM 16 bit 43 memcpy_by_audio_format( 44 buffer, AUDIO_FORMAT_PCM_16_BIT, 45 bytes, AUDIO_FORMAT_PCM_8_BIT, size); 46 47 uint8_t check[size]; 48 memcpy_by_audio_format( 49 check, AUDIO_FORMAT_PCM_8_BIT, 50 buffer, AUDIO_FORMAT_PCM_16_BIT, size); 51 EXPECT_EQ(0, memcmp(check, bytes, size)); 52 } 53 54 class FormatTest : public testing::TestWithParam<std::tuple<audio_format_t, audio_format_t>> 55 { 56 }; 57 58 TEST_P(FormatTest, memcpy_by_audio_format) 59 { 60 // fetch parameters 61 const auto param = GetParam(); 62 const audio_format_t src_encoding = std::get<0>(param); 63 const audio_format_t dst_encoding = std::get<1>(param); 64 65 // either source or destination (or both) need to be a common format 66 if (!is_common_format(src_encoding) && !is_common_format(dst_encoding)) { 67 printf("skip conversion src:%#x dst:%#x\n", src_encoding, dst_encoding); 68 return; 69 } 70 71 constexpr size_t SAMPLES = UINT8_MAX; 72 constexpr audio_format_t orig_encoding = AUDIO_FORMAT_PCM_16_BIT; 73 int16_t orig_data[SAMPLES]; 74 75 fillRamp(orig_data); 76 77 // data buffer for in-place conversion (uint32_t is maximum sample size of 4 bytes) 78 uint32_t data[SAMPLES]; 79 // check buffer is used to compare out-of-place vs in-place conversion. 80 uint32_t check[SAMPLES]; 81 82 printf("trying conversion src:%#x dst:%#x\n", src_encoding, dst_encoding); 83 fflush(stdout); 84 // Copy original data to data buffer at src_encoding. 85 memcpy_by_audio_format( 86 data, src_encoding, 87 orig_data, orig_encoding, SAMPLES); 88 89 // Convert from src encoding to dst encoding. 90 memcpy_by_audio_format( 91 check, dst_encoding, 92 data, src_encoding, SAMPLES); 93 94 // Check in-place is same as out-of-place conversion. 95 memcpy_by_audio_format( 96 data, dst_encoding, 97 data, src_encoding, SAMPLES); 98 EXPECT_EQ(0, memcmp(check, data, SAMPLES * audio_bytes_per_sample(dst_encoding))); 99 100 // Go back to the original data encoding for comparison. 101 memcpy_by_audio_format( 102 data, orig_encoding, 103 data, dst_encoding, SAMPLES); 104 105 // Raw byte compare at the original encoding must succeed - our conversions 106 // must be lossless for PCM 8 bit representation which orig_data was constructed from. 107 EXPECT_EQ(0, 108 memcmp(data, orig_data, SAMPLES * audio_bytes_per_sample(orig_encoding))); 109 } 110 111 INSTANTIATE_TEST_CASE_P(FormatVariations, FormatTest, ::testing::Combine( 112 ::testing::Values( 113 AUDIO_FORMAT_PCM_8_BIT, 114 AUDIO_FORMAT_PCM_16_BIT, 115 AUDIO_FORMAT_PCM_FLOAT, 116 AUDIO_FORMAT_PCM_24_BIT_PACKED, 117 AUDIO_FORMAT_PCM_32_BIT, 118 AUDIO_FORMAT_PCM_8_24_BIT 119 ), 120 ::testing::Values( 121 AUDIO_FORMAT_PCM_8_BIT, 122 AUDIO_FORMAT_PCM_16_BIT, 123 AUDIO_FORMAT_PCM_FLOAT, 124 AUDIO_FORMAT_PCM_24_BIT_PACKED, 125 AUDIO_FORMAT_PCM_32_BIT, 126 AUDIO_FORMAT_PCM_8_24_BIT 127 ))); 128